Merge "Ensure that LLOB sensor is names similr to other android sensors." into oc-dev
diff --git a/Android.bp b/Android.bp
index f3426e8..f6aacd2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -2,8 +2,14 @@
 
 cc_library_headers {
     name: "libhardware_headers",
-    header_libs: ["libsystem_headers"],
-    export_header_lib_headers: ["libsystem_headers"],
+    header_libs: [
+        "libaudio_system_headers",
+        "libsystem_headers",
+    ],
+    export_header_lib_headers: [
+        "libaudio_system_headers",
+        "libsystem_headers"
+    ],
 
     export_include_dirs: ["include"],
     vendor_available: true,
diff --git a/modules/gralloc/Android.mk b/modules/gralloc/Android.mk
index cdd8d07..ff5808d 100644
--- a/modules/gralloc/Android.mk
+++ b/modules/gralloc/Android.mk
@@ -28,6 +28,8 @@
 	framebuffer.cpp \
 	mapper.cpp
 
+LOCAL_HEADER_LIBRARIES := libhardware_headers
+
 LOCAL_MODULE := gralloc.default
 LOCAL_CFLAGS:= -DLOG_TAG=\"gralloc\" -Wno-missing-field-initializers
 ifeq ($(TARGET_USE_PAN_DISPLAY),true)
diff --git a/modules/sensors/dynamic_sensor/Android.mk b/modules/sensors/dynamic_sensor/Android.mk
index 38a658a..cdc1929 100644
--- a/modules/sensors/dynamic_sensor/Android.mk
+++ b/modules/sensors/dynamic_sensor/Android.mk
@@ -32,7 +32,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := libdynamic_sensor_ext
 LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_OWNER := google
+# intended to be integrated into hal, thus proprietary
 LOCAL_PROPRIETARY_MODULE := true
 
 LOCAL_CFLAGS += $(COMMON_CFLAGS) -DLOG_TAG=\"DynamicSensorExt\"
@@ -61,7 +61,7 @@
 LOCAL_MODULE := sensors.dynamic_sensor_hal
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_OWNER := google
+# hal module, thus proprietary
 LOCAL_PROPRIETARY_MODULE := true
 
 LOCAL_CFLAGS += $(COMMON_CFLAGS) -DLOG_TAG=\"DynamicSensorHal\"
@@ -83,3 +83,6 @@
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
 
 include $(BUILD_SHARED_LIBRARY)
+
+include $(LOCAL_PATH)/HidUtils/Android.mk
+
diff --git a/modules/sensors/dynamic_sensor/HidUtils/Android.mk b/modules/sensors/dynamic_sensor/HidUtils/Android.mk
new file mode 100644
index 0000000..5a1d890
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/Android.mk
@@ -0,0 +1,99 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+COMMON_CFLAGS := -Wall -Werror -Wextra
+
+hidparser_src := \
+    HidGlobal.cpp \
+    HidItem.cpp \
+    HidLocal.cpp \
+    HidParser.cpp \
+    HidReport.cpp \
+    HidTree.cpp
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libhidparser
+LOCAL_MODULE_TAGS := optional
+# indended to be used by hal components, thus propietary
+LOCAL_PROPRIETARY_MODULE := true
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS) -DLOG_TAG=\"HidUtil\"
+LOCAL_SRC_FILES := $(hidparser_src)
+LOCAL_SHARED_LIBRARIES := libbase
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+include $(BUILD_SHARED_LIBRARY)
+
+#
+# host side shared library (for host test, example, etc)
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := libhidparser_host
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS)
+
+LOCAL_SRC_FILES := $(hidparser_src)
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+include $(BUILD_HOST_SHARED_LIBRARY)
+
+#
+# Example of HidParser
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := hidparser_example
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS)
+LOCAL_SRC_FILES := \
+    $(hidparser_src) \
+    test/HidParserExample.cpp \
+    test/TestHidDescriptor.cpp
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/test
+include $(BUILD_HOST_EXECUTABLE)
+
+#
+# Another example of HidParser
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := hidparser_example2
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS)
+LOCAL_SRC_FILES := \
+    $(hidparser_src) \
+    test/HidParserExample2.cpp \
+    test/TestHidDescriptor.cpp
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/test
+include $(BUILD_HOST_EXECUTABLE)
+
+#
+# Test for TriState template
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := tristate_test
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS += $(COMMON_CFLAGS)
+LOCAL_SRC_FILES := test/TriStateTest.cpp
+
+LOCAL_STATIC_LIBRARIES := \
+     libgtest \
+     libgtest_main
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/test
+include $(BUILD_HOST_NATIVE_TEST)
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidDefs.h b/modules/sensors/dynamic_sensor/HidUtils/HidDefs.h
new file mode 100644
index 0000000..05445db
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidDefs.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDDEFS_H_
+#define HIDUTIL_HIDDEFS_H_
+
+namespace HidUtil {
+
+// HID specification constants definition
+//
+// Definitions are from HID specification v1.11, which can be obtained from http://www.usb.org
+//
+// Preferred namespace for namespace restriction than enum class as enum class has strong type
+// which is inconvenient in a parser, in which input binary values has to be compared with these
+// definitions frequnetly.
+namespace HidDef {
+// Hid spec 6.2.2.3
+namespace TagType {
+enum {
+    MAIN,
+    GLOBAL,
+    LOCAL,
+    RESERVED
+};
+} // namespace TagType
+
+// HID spec 6.2.2.4
+namespace ReportFlag {
+enum {
+    DATA_CONST = 1,
+    ARRAY_VARIABLE = 2,
+    WRAP = 4,
+    NONLINEAR = 8,
+    NO_PREFERRED = 0x10,
+    NULL_STATE = 0x20,
+    VOLATILE = 0x40,
+    // bit 7 reserved
+    BUFFERED_BYTES = 0x100
+};
+} // namespace ReportFlag
+
+// HID spec 6.2.2.5
+namespace MainTag {
+enum {
+    INPUT = 8,
+    OUTPUT = 9,
+    COLLECTION = 10,
+    FEATURE = 11,
+    END_COLLECTION = 12,
+    LONG_ITEM = 15,
+};
+} // namespace MainTag
+
+// HID spec 6.2.2.6
+namespace CollectionType {
+enum {
+    PHYSICAL = 0,
+    APPLICATION,
+    LOGICAL,
+    REPORT,
+    NAMED_ARRAY,
+    USAGE_SWITCH,
+    USAGE_MODIFIER
+};
+} // namespace CollectionType
+
+// HID spec 6.2.2.7
+namespace GlobalTag {
+enum {
+    USAGE_PAGE,
+    LOGICAL_MINIMUM,
+    LOGICAL_MAXIMUM,
+    PHYSICAL_MINIMUM,
+    PHYSICAL_MAXIMUM,
+    UNIT_EXPONENT,
+    UNIT,
+    REPORT_SIZE,
+    REPORT_ID,
+    REPORT_COUNT,
+    PUSH,
+    POP
+};
+} //namespace GlobalTag
+
+// HID spec 6.2.2.8
+namespace LocalTag {
+enum HidLocalTag {
+    USAGE,
+    USAGE_MINIMUM,
+    USAGE_MAXIMUM,
+    DESIGNATOR_INDEX,
+    DESIGNATOR_MINIMUM,
+    DESIGNATOR_MAXIMUM,
+    // there is a hole here in the spec
+    STRING_INDEX = 7,
+    STRING_MINIMUM,
+    STRING_MAXIMUM,
+    DELIMITOR
+};
+} // namespace LocalTag
+
+} //namespace HidDef
+} //namespace HidUtil
+
+#endif // HIDUTIL_HIDDEFS_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidGlobal.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidGlobal.cpp
new file mode 100644
index 0000000..8a4713b
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidGlobal.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidDefs.h"
+#include "HidGlobal.h"
+#include "HidLog.h"
+
+namespace HidUtil {
+using namespace HidDef::GlobalTag;
+
+bool HidGlobal::append(const HidItem &i) {
+    using namespace HidDef::TagType;
+    if (i.type != GLOBAL) {
+        LOG_E << "HidGlobal::append cannot process tag that is not global, " << i << LOG_ENDL;
+        return false;
+    }
+
+    if (i.tag == PUSH || i.tag == POP) {
+        LOG_E << "PUSH and POP should be handled in HidGlobalStack, " << i << LOG_ENDL;
+        return false;
+    }
+
+    int signedInteger;
+    unsigned unsignedInteger;
+    bool signedError = !i.dataAsSigned(&signedInteger);
+    bool unsignedError = !i.dataAsUnsigned(&unsignedInteger);
+
+    bool valueError = false;
+    bool ret = true;
+    switch (i.tag) {
+        case USAGE_PAGE:
+            usagePage = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        case LOGICAL_MINIMUM:
+            logicalMin = signedInteger;
+            valueError = signedError;
+            break;
+        case LOGICAL_MAXIMUM:
+            logicalMax = signedInteger;
+            valueError = signedError;
+            break;
+        case PHYSICAL_MINIMUM:
+            physicalMin = signedInteger;
+            valueError = signedError;
+            break;
+        case PHYSICAL_MAXIMUM:
+            physicalMax = signedInteger;
+            valueError = signedError;
+            break;
+        case UNIT_EXPONENT:
+            exponent = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        case UNIT:
+            unit = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        case REPORT_SIZE:
+            reportSize = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        case REPORT_ID:
+            reportId = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        case REPORT_COUNT:
+            reportCount = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        default:
+            LOG_E << "unknown global tag, " << i << LOG_ENDL;
+            ret = false;
+    }
+
+    if (valueError) {
+        LOG_E << "Cannot get signed / unsigned data at " << i << LOG_ENDL;
+        ret = false;
+    }
+    return ret;
+}
+
+bool HidGlobalStack::append(const HidItem &i) {
+    using namespace HidDef::TagType;
+    if (i.type != GLOBAL) {
+        return false;
+    }
+
+    bool ret = true;
+    if (i.tag == PUSH) {
+        mStack.push_back(top());
+    } else if (i.tag == POP) {
+        mStack.pop_back();
+        if (mStack.size() == 0) {
+            mStack.push_back(HidGlobal()); // fail-safe
+            ret = false;
+        }
+    } else {
+        ret = mStack.back().append(i);
+    }
+    return ret;
+}
+
+HidGlobalStack::HidGlobalStack() {
+    // default element
+    mStack.push_back(HidGlobal());
+}
+
+const HidGlobal& HidGlobalStack::top() const {
+    return mStack.back();
+}
+
+} // namespace HidUtil
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidGlobal.h b/modules/sensors/dynamic_sensor/HidUtils/HidGlobal.h
new file mode 100644
index 0000000..b9139d0
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidGlobal.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDGLOBAL_H_
+#define HIDUTIL_HIDGLOBAL_H_
+
+#include "HidItem.h"
+#include "TriState.h"
+
+namespace HidUtil {
+// A set of global states that parser has to keep track during parsing.
+// They are all specified in HID spec v1.11 section 6.2.2.7
+struct HidGlobal {
+    // add a token and change global states, returns value indicates if operation is successful
+    bool append(const HidItem &i);
+
+    tri_uint usagePage;
+    tri_int  logicalMin;
+    tri_int  logicalMax;
+    tri_int  physicalMin;
+    tri_int  physicalMax;
+    tri_uint exponent;
+    tri_uint unit;
+    tri_uint reportSize;
+    tri_uint reportId;
+    tri_uint reportCount;
+};
+
+// HID specs allows PUSH and POP to save a snapshot of current global states and come back to the
+// saved sates later. HidStack manages this logic. Note that PUSH and POP are also HidItems, so
+// there is no explicit push and pop function in this stack implementation.
+class HidGlobalStack {
+public:
+    HidGlobalStack();
+
+    // add a token and change global states, returns value indicates if operation is successful
+    // it the token is push/pop, the stack push/pop accordingly.
+    bool append(const HidItem &i);
+
+    // get reference to top element on the stack
+    const HidGlobal& top() const;
+private:
+    std::vector<HidGlobal> mStack;
+};
+
+} //namespace HidUtil
+
+#endif // HIDUTIL_HIDGLOABL_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidItem.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidItem.cpp
new file mode 100644
index 0000000..e704db7
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidItem.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidItem.h"
+#include "HidDefs.h"
+#include "StreamIoUtil.h"
+#include <iostream>
+
+namespace HidUtil {
+
+bool HidItem::dataAsUnsigned(unsigned int *out) const  {
+    if (data.size() > 4 || data.size() == 0) {
+        return false;
+    }
+
+    *out = 0;
+    int shift = 0;
+
+    for (auto i : data) {
+        *out |= (i << shift);
+        shift += 8;
+    }
+    return true;
+}
+
+bool HidItem::dataAsSigned(int *out) const {
+    unsigned int u;
+    if (!dataAsUnsigned(&u)) {
+        return false;
+    }
+    size_t bitSize_1 = data.size() * 8 - 1;
+    unsigned int sign = u & (1 << bitSize_1);
+    *out = u | ((sign == 0) ? 0 : ( ~0 << bitSize_1));
+    return true;
+}
+
+std::vector<HidItem> HidItem::tokenize(const uint8_t *begin, size_t size) {
+    // construct a stream
+    charvectorbuf<unsigned char> buf(begin, size);
+    std::istream is(&buf);
+    return tokenize(is);
+}
+
+std::vector<HidItem> HidItem::tokenize(const std::vector<uint8_t> &descriptor) {
+    // construct a stream
+    charvectorbuf<unsigned char> buf(descriptor);
+    std::istream is(&buf);
+    return tokenize(is);
+}
+
+std::vector<HidItem> HidItem::tokenize(std::istream &is) {
+    std::vector<HidItem> hidToken;
+
+    // this is important to avoid skipping characters
+    is.unsetf(std::ios_base::skipws);
+    while (!is.eof()) {
+        HidItem i;
+        is >> i;
+        if (i.valid) {
+            hidToken.push_back(i);
+        } else {
+            break;
+        }
+    }
+    return hidToken;
+}
+
+std::istream& operator>>(std::istream &is, HidUtil::HidItem &h) {
+    using namespace HidUtil::HidDef::MainTag;
+    using namespace HidUtil::HidDef::TagType;
+
+    h.valid = false;
+    h.offset = is.tellg();
+    h.byteSize = 0;
+    unsigned char first;
+    is >> first;
+    if (!is.eof()) {
+        static const size_t lenTable[] = { 0, 1, 2, 4 };
+        size_t len = lenTable[first & 0x3]; // low 2 bits are length descriptor
+        h.tag = (first >> 4);
+        h.type = (first & 0xC) >> 2;
+
+        if (h.tag == LONG_ITEM && h.type == RESERVED) { // long item
+            //long item
+            unsigned char b = 0;
+            is >> b;
+            len = b;
+            is >> b;
+            h.tag = b;
+        }
+
+        h.data.resize(len);
+        for (auto &i : h.data) {
+            if (is.eof()) {
+                break;
+            }
+            is >> i;
+        }
+        h.byteSize = (ssize_t) is.tellg() - h.offset;
+        h.valid = !is.eof();
+    }
+
+    return is;
+}
+
+std::ostream& operator<<(std::ostream &os, const HidUtil::HidItem &h) {
+    os << "offset: " << h.offset << ", size: " << h.byteSize
+       << ", tag: " << h.tag << ", type: " << h.type << ", data: ";
+    if (h.data.empty()) {
+        os << "[empty]";
+    } else {
+        os << h.data.size() << " byte(s) {";
+        for (auto i : h.data) {
+            os << (int) i << ", ";
+        }
+        os << "}";
+    }
+    return os;
+}
+} // namespace HidUtil
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidItem.h b/modules/sensors/dynamic_sensor/HidUtils/HidItem.h
new file mode 100644
index 0000000..cec79e9
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidItem.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDITEM_H_
+#define HIDUTIL_HIDITEM_H_
+
+#include <cstdlib>
+#include <vector>
+#include <istream>
+#include <ostream>
+
+namespace HidUtil {
+
+struct HidItem {
+    bool valid;
+    unsigned int type;
+    unsigned int tag;
+    ssize_t offset;
+    ssize_t byteSize;
+    std::vector<uint8_t> data;
+
+    bool dataAsUnsigned(unsigned int *out) const;
+    bool dataAsSigned(int *out) const;
+
+    // friend stream functions
+    friend std::istream& operator>>(std::istream &is, HidItem &h);
+    friend std::ostream& operator<<(std::ostream &os, const HidItem &h);
+
+    // tokenize from a unsigned char vector
+    static std::vector<HidItem> tokenize(const std::vector<uint8_t> &descriptor);
+    static std::vector<HidItem> tokenize(const uint8_t *begin, size_t size);
+    static std::vector<HidItem> tokenize(std::istream &is);
+};
+
+// parsing in from binary stream
+std::istream& operator>>(std::istream &is, HidUtil::HidItem &h);
+
+// output as human readable string to stream
+std::ostream& operator<<(std::ostream &os, const HidUtil::HidItem &h);
+} //namespace HidUtil
+
+#endif // HIDUTIL_HIDITEM_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidLocal.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidLocal.cpp
new file mode 100644
index 0000000..8f17abe
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidLocal.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidDefs.h"
+#include "HidLocal.h"
+#include "HidLog.h"
+#include <cstddef>
+
+namespace HidUtil {
+
+constexpr uint32_t INVALID_USAGE = 0xFFFF;
+constexpr uint32_t INVALID_DESIGNATOR = 0xFFFF;
+constexpr uint32_t INVALID_STRING = 0xFFFF;
+
+uint32_t HidLocal::getUsage(size_t index) const {
+    if (usage.empty()) {
+        return INVALID_USAGE;
+    }
+    return (index >= usage.size()) ? usage.back() : usage[index];
+}
+
+uint32_t HidLocal::getDesignator(size_t index) const {
+    if (designator.empty()) {
+        return INVALID_DESIGNATOR;
+    }
+    return (index >= designator.size()) ? designator.back() : designator[index];
+}
+
+uint32_t HidLocal::getString(size_t index) const {
+    if (string.empty()) {
+        return INVALID_STRING;
+    }
+    return (index >= string.size()) ? string.back() : string[index];
+}
+
+void HidLocal::clear() {
+    *this = HidLocal();
+}
+
+bool HidLocal::append(const HidItem &i) {
+    using namespace HidDef::LocalTag;
+
+    bool ret = true;
+    unsigned unsignedInteger;
+    bool unsignedError = !i.dataAsUnsigned(&unsignedInteger);
+    bool valueError = false;
+
+    switch (i.tag) {
+        case USAGE:
+            usage.push_back(unsignedInteger);
+            valueError = unsignedError;
+            break;
+        case USAGE_MINIMUM:
+            usageMin = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        case USAGE_MAXIMUM:
+            if (!usageMin.isSet()) {
+                LOG_E << "usage min not set when saw usage max " << i << LOG_ENDL;
+                ret = false;
+            } else {
+                uint32_t usagemax = unsignedInteger;
+                valueError = unsignedError;
+                for (size_t j = usageMin.get(0); j <= usagemax; ++j) {
+                    usage.push_back(j);
+                }
+                usageMin.clear();
+            }
+            break;
+        case STRING_INDEX:
+            string.push_back(unsignedInteger);
+            valueError = unsignedError;
+            break;
+        case STRING_MINIMUM:
+            stringMin = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        case STRING_MAXIMUM: {
+            if (!usageMin.isSet()) {
+                LOG_E << "string min not set when saw string max " << i << LOG_ENDL;
+                ret = false;
+            } else {
+                uint32_t stringMax = unsignedInteger;
+                valueError = unsignedError;
+                for (size_t j = stringMin.get(0); j <= stringMax; ++j) {
+                    string.push_back(j);
+                }
+                stringMin.clear();
+            }
+            break;
+        }
+        case DELIMITOR:
+            delimeter = unsignedInteger;
+            valueError = unsignedError;
+            break;
+        default:
+            LOG_E << "unknown local tag, " << i << LOG_ENDL;
+            ret = false;
+    }
+    if (valueError) {
+        LOG_E << "Cannot get unsigned data at " << i << LOG_ENDL;
+        ret = false;
+    }
+    return ret;
+}
+} //namespace HidUtil
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidLocal.h b/modules/sensors/dynamic_sensor/HidUtils/HidLocal.h
new file mode 100644
index 0000000..1c30b30
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidLocal.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDLOCAL_H_
+#define HIDUTIL_HIDLOCAL_H_
+
+#include "HidItem.h"
+#include "TriState.h"
+#include <cstddef>
+#include <vector>
+
+namespace HidUtil {
+
+// A set of local states that parser has to keep track during parsing.
+// They are all specified in HID spec v1.11 section 6.2.2.8
+struct HidLocal {
+    // add a token to change local states, return value indicates if operation is successful
+    bool append(const HidItem &i);
+    // clear all local states. This need to be done after each main tag
+    void clear();
+
+    // multiple usage, designator or strings may exist for single input/output/feature report
+    uint32_t getUsage(size_t index) const;
+    uint32_t getDesignator(size_t index) const;
+    uint32_t getString(size_t index) const;
+
+    std::vector<uint32_t> usage;
+    // keep track of usage min when expecting a usage max
+    tri_uint usageMin;
+
+    std::vector<uint32_t> designator;
+    // keep track of designator min when expecting designator max
+    tri_uint designatorMin;
+
+    std::vector<uint32_t> string;
+    // keep track of string min when expecting string max
+    tri_uint stringMin;
+
+    tri_uint delimeter;
+};
+} // namespace HidUtil
+
+#endif // HIDUTIL_HIDLOCAL_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidLog.h b/modules/sensors/dynamic_sensor/HidUtils/HidLog.h
new file mode 100644
index 0000000..677de57
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidLog.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDLOG_H_
+#define HIDUTIL_HIDLOG_H_
+
+#if defined(__ANDROID__) && !defined(LOG_TO_CONSOLE)
+#include <android-base/logging.h>
+#define LOG_ENDL ""
+#define LOG_E LOG(ERROR)
+#define LOG_W LOG(WARNING)
+#define LOG_I LOG(INFO)
+#define LOG_D LOG(DEBUG)
+#define LOG_V LOG(VERBOSE)
+#else
+#include <iostream>
+#define LOG_ENDL std::endl
+#define LOG_E (std::cerr << "E: ")
+#define LOG_W (std::cerr << "W: ")
+#define LOG_I (std::cerr << "I: ")
+#define LOG_D (std::cerr << "D: ")
+#define LOG_V (std::cerr << "V: ")
+#endif
+
+#endif // HIDUTIL_HIDLOG_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp
new file mode 100644
index 0000000..5efaf65
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidParser.cpp
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidDefs.h"
+#include "HidParser.h"
+#include "HidLog.h"
+#include <iostream>
+#include <iomanip>
+
+namespace HidUtil {
+
+void HidParser::reset() {
+    mGlobalStack = HidGlobalStack();
+    mLocal = HidLocal();
+    mTree = std::make_shared<HidTreeNode>();
+    mCurrent = mTree;
+}
+
+bool HidParser::parse(const std::vector<HidItem> &token) {
+    // Clean up internal states of the parser for a new stream of descriptor token
+    reset();
+
+    bool ret = true;
+    using namespace HidDef::TagType;
+
+    for (auto &i : token) {
+        switch (i.type) {
+            case MAIN:
+                ret = processMainTag(i);
+                break;
+            case GLOBAL:
+                ret = mGlobalStack.append(i);
+                break;
+            case LOCAL:
+                ret = mLocal.append(i);
+                break;
+            default:
+                LOG_E << "HidParser found illegal HidItem: " << i << LOG_ENDL;
+                ret = false;
+        }
+
+        // in case a parse failure, quit prematurely
+        if (!ret) {
+            break;
+        }
+    }
+    return ret;
+}
+
+bool HidParser::processMainTag(const HidItem &i) {
+    using namespace HidDef::MainTag;
+    using namespace HidDef::ReportFlag;
+
+    bool ret = true;
+    switch (i.tag) {
+        case COLLECTION: {
+            unsigned int collectionType;
+            if (!i.dataAsUnsigned(&collectionType)) {
+                LOG_E << "Cannot get collection type at offset " << i.offset << LOG_ENDL;
+                ret = false;
+                break;
+            }
+            unsigned int fullUsage =
+                    mGlobalStack.top().usagePage.get(0) << 16 | mLocal.getUsage(0);
+            mCurrent = mCurrent->addChild(
+                    std::make_shared<HidTreeNode>(mCurrent, collectionType, fullUsage));
+            break;
+        }
+        case END_COLLECTION:
+            mCurrent = mCurrent->getParent();
+            if (!mCurrent) {
+                // trigger parse failure so that mCurrent will not be accessed
+                LOG_E << "unmatched END_COLLECTION at " << i.offset << LOG_ENDL;
+                ret = false;
+            }
+            break;
+        case INPUT:
+        case OUTPUT:
+        case FEATURE: {
+            unsigned int reportType = i.tag;
+            unsigned int flag;
+            if (!i.dataAsUnsigned(&flag)) {
+                LOG_E << "Cannot get report flag at offset " << i.offset << LOG_ENDL;
+                ret = false;
+                break;
+            }
+            const HidGlobal &top = mGlobalStack.top();
+
+            // usage page, local min/max, report size and count have to be defined at report
+            // definition.
+            if (!(top.usagePage.isSet() && top.logicalMin.isSet() && top.logicalMax.isSet()
+                  && top.reportSize.isSet() && top.reportCount.isSet())) {
+                LOG_E << "Report defined at " << i.offset
+                      << " does not have all mandatory fields set" << LOG_ENDL;
+                ret = false;
+                break;
+            }
+            if (top.reportSize.get(0) > 32) {
+                LOG_E << "Report defined at " << i.offset
+                      << " has unsupported report size(> 32 bit)" << LOG_ENDL;
+                ret = false;
+                break;
+            }
+
+            HidReport report(reportType, flag, top, mLocal);
+            mReport.push_back(report);
+            std::shared_ptr<HidTreeNode> node(new HidReportNode(mCurrent, report));
+            mCurrent->addChild(node);
+            break;
+        }
+        default:
+            LOG_E << "unknown main tag, " << i << LOG_ENDL;
+            ret = false;
+    }
+    // locals is cleared after any main tag according to HID spec
+    mLocal.clear();
+    return ret;
+}
+
+bool HidParser::parse(const unsigned char *begin, size_t size) {
+    std::vector<HidItem> hidItemVector = HidItem::tokenize(begin, size);
+    return parse(hidItemVector);
+}
+
+void HidParser::filterTree() {
+    if (mTree != nullptr) {
+        filterTree(mTree);
+    }
+}
+
+void HidParser::filterTree(std::shared_ptr<HidTreeNode> &node) {
+    if (node->isReportCollection()) {
+        std::shared_ptr<HidReportNode> reportNode =
+                std::static_pointer_cast<HidReportNode>(node->getChildren().front());
+        if (reportNode != nullptr) {
+            reportNode->collapse(node->getFullUsage());
+            node = reportNode;
+        }
+    } else {
+        for (auto &i : node->getChildren()) {
+            filterTree(i);
+        }
+    }
+}
+
+HidParser::DigestVector HidParser::generateDigest(
+        const std::unordered_set<unsigned int> &interestedUsage) {
+    DigestVector digestVector;
+    digest(&digestVector, mTree, interestedUsage);
+    return digestVector;
+}
+
+void HidParser::digest(HidParser::DigestVector *digestVector,
+                       const std::shared_ptr<HidTreeNode> &node,
+                       const std::unordered_set<unsigned int> &interestedUsage) {
+    if (digestVector == nullptr) {
+        return;
+    }
+
+    if (node->isUsageCollection()
+            && interestedUsage.find(node->getFullUsage()) != interestedUsage.end()) {
+        // this collection contains the usage interested
+        ReportSetGroup reportSetGroup;
+
+        // one layer deep search
+        for (auto &i : node->getChildren()) {
+            // skip all nodes that is not a report node
+            if (i->getNodeType() != HidTreeNode::TYPE_REPORT) {
+                continue;
+            }
+            const HidReport &report =
+                    std::static_pointer_cast<HidReportNode>(i)->getReport();
+
+            unsigned int id = report.getReportId();;
+            if (reportSetGroup.find(id) == reportSetGroup.end()) {
+                // create an id group if it is not created
+                reportSetGroup.emplace(id, ReportSet());
+            }
+
+            ReportSet &reportGroup = reportSetGroup[id];
+            switch(report.getType()) {
+                using namespace HidDef::MainTag;
+                case FEATURE:
+                    reportGroup[REPORT_TYPE_FEATURE].push_back(report);
+                    break;
+                case INPUT:
+                    reportGroup[REPORT_TYPE_INPUT].push_back(report);
+                    break;
+                case OUTPUT:
+                    reportGroup[REPORT_TYPE_OUTPUT].push_back(report);
+                    break;
+            }
+        }
+        ReportDigest digest = {
+            .fullUsage = node->getFullUsage(),
+            .packets = convertGroupToPacket(reportSetGroup)
+        };
+        digestVector->emplace_back(digest);
+    } else {
+        for (const auto &child : node->getChildren()) {
+            if (child->getNodeType() == HidTreeNode::TYPE_NORMAL) {
+                // only follow into collection nodes
+                digest(digestVector, child, interestedUsage);
+            }
+        }
+    }
+}
+
+std::vector<HidParser::ReportPacket> HidParser::convertGroupToPacket(
+        const HidParser::ReportSetGroup &group) {
+    std::vector<ReportPacket> packets;
+
+    const std::vector<int> types = {REPORT_TYPE_FEATURE, REPORT_TYPE_INPUT, REPORT_TYPE_OUTPUT};
+
+    for (const auto &setPair : group) {
+        unsigned int id = setPair.first;
+        for (auto type : types) {
+            const auto &reports = setPair.second[type]; // feature
+
+            // template
+            ReportPacket packet = {
+                .type = type,
+                .id = id,
+                .bitSize = 0
+            };
+
+            for (const auto &r : reports) {
+                auto logical = r.getLogicalRange();
+                auto physical = r.getPhysicalRange();
+
+                int64_t offset = physical.first - logical.first;
+                double scale = static_cast<double>((physical.second - physical.first))
+                        / (logical.second - logical.first);
+                scale *= r.getExponentValue();
+
+                ReportItem digest = {
+                    .usage = r.getFullUsage(),
+                    .id = id,
+                    .minRaw = logical.first,
+                    .maxRaw = logical.second,
+                    .a = scale,
+                    .b = offset,
+                    .bitOffset = packet.bitSize,
+                    .bitSize = r.getSize(),
+                    .count = r.getCount(),
+                    .unit = r.getUnit(),
+                };
+                packet.reports.push_back(digest);
+                packet.bitSize += digest.bitSize * digest.count;
+            }
+            if (!packet.reports.empty()) {
+                packets.push_back(std::move(packet));
+            }
+        }
+    }
+    return packets;
+}
+
+static std::string reportTypeToString(int reportType) {
+    switch (reportType) {
+        case HidParser::REPORT_TYPE_INPUT:
+            return "INPUT";
+        case HidParser::REPORT_TYPE_OUTPUT:
+            return "OUTPUT";
+        case HidParser::REPORT_TYPE_FEATURE:
+            return "FEATURE";
+        default:
+            return "INVALID REPORT";
+    }
+}
+
+std::ostream& operator<<(std::ostream &os, const HidParser::DigestVector &digests) {
+    for (const auto &i : digests) {
+        os << "Usage: 0x" << std::hex  << i.fullUsage << std::dec
+           << ", " << i.packets.size() << " report packet:" << LOG_ENDL;
+        for (const auto &packet : i.packets) {
+            os << reportTypeToString(packet.type) << " id: " << packet.id
+               << " size: " << packet.bitSize
+               << "b(" << packet.getByteSize() << "B), "
+               << packet.reports.size() << " entries" << LOG_ENDL;
+
+            for (const auto &report : packet.reports) {
+                double min, max;
+                report.decode(report.mask(report.minRaw), &min);
+                report.decode(report.mask(report.maxRaw), &max);
+
+                os << "  " << report.bitOffset << " size: " << report.bitSize
+                   << ", count: " << report.count
+                   << ", usage: " << std::hex << std::setfill('0') << std::setw(8)
+                   << report.usage << std::dec
+                   << ", min: " << report.minRaw << ", max: " << report.maxRaw
+                   << ", minDecoded: " << min
+                   << ", maxDecoded: " << max
+                   << ", a: " << report.a << ", b: " << report.b
+                   << std::hex
+                   << ", minRawHex: 0x" << report.mask(report.minRaw)
+                   << ", maxRawHex: 0x" << report.mask(report.maxRaw)
+                   << ", rawMasked: 0x" << report.rawMask()
+                   << std::dec << LOG_ENDL;
+            }
+        }
+        os << LOG_ENDL;
+    }
+    os << LOG_ENDL;
+    return os;
+}
+} // namespace HidUtil
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidParser.h b/modules/sensors/dynamic_sensor/HidUtils/HidParser.h
new file mode 100644
index 0000000..4ef5ec6
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidParser.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDPARSER_H_
+#define HIDUTIL_HIDPARSER_H_
+
+#include "HidItem.h"
+#include "HidTree.h"
+#include "HidGlobal.h"
+#include "HidLocal.h"
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+#include <array>
+#include <ostream>
+
+namespace HidUtil {
+class HidParser {
+public:
+    enum {
+        REPORT_TYPE_FEATURE = 0,
+        REPORT_TYPE_INPUT = 1,
+        REPORT_TYPE_OUTPUT = 2
+    };
+
+    struct ReportItem;
+    struct ReportPacket;
+
+    // report (including input output and feature) grouped by full usage
+    struct ReportDigest {
+        unsigned int fullUsage;
+        std::vector<ReportPacket> packets;
+    };
+
+    typedef std::vector<ReportDigest> DigestVector;
+
+    // parse HID descriptor
+    bool parse(const std::vector<HidItem> &token);
+    bool parse(const unsigned char *begin, size_t size);
+
+    // filter the tree to eliminate single child report leaf node causes by usage array type
+    // reports
+    void filterTree();
+
+    // generate a list of report digest for all interested usage. It will automatically
+    // call filterTree().
+    DigestVector generateDigest(const std::unordered_set<unsigned int> &interestedUsage);
+
+    // get parsed tree (filtered or not filtered)
+    const std::shared_ptr<HidTreeNode> getTree() const { return mTree; }
+
+    // get all parsed report in a parsed form.
+    const std::vector<HidReport>& getReport() const { return mReport; }
+
+private:
+    typedef std::array<std::vector<HidReport>, 3> ReportSet;
+    typedef std::unordered_map<unsigned int /* reportId */, ReportSet> ReportSetGroup;
+
+    // helper subroutines
+    void reset();
+    bool processMainTag(const HidItem &i);
+    static void filterTree(std::shared_ptr<HidTreeNode> &node);
+    static void digest(
+            DigestVector *digestVector,
+            const std::shared_ptr<HidTreeNode> &node,
+            const std::unordered_set<unsigned int> &interestedUsage);
+    static std::vector<ReportPacket> convertGroupToPacket(const ReportSetGroup &group);
+
+    HidGlobalStack mGlobalStack;
+    HidLocal mLocal;
+    std::shared_ptr<HidTreeNode> mTree;
+    std::shared_ptr<HidTreeNode> mCurrent;
+    std::vector<HidReport> mReport;
+};
+
+struct HidParser::ReportItem {
+    unsigned int usage;
+    unsigned int id;
+    int type; // feature, input or output
+
+    int64_t minRaw;
+    int64_t maxRaw;
+
+    // conversion for float point values
+    // real value = (signExtendIfNeeded(raw) + b) * a
+    // raw value = mask(real/a - b);
+    //
+    // conversion for integer values
+    // real value = signExtendedIfNeeded(raw) + b;
+    // raw value = mask(real - b);
+    double a; // scaling
+    int64_t b; // offset
+    unsigned int unit;
+
+    size_t bitOffset;
+    size_t bitSize; // bit length per unit
+    size_t count;
+
+    // helper function
+    bool isSigned() const {
+        return minRaw < 0;
+    }
+
+    bool isByteAligned() const {
+        return (bitOffset & 7) == 0 && (bitSize & 7) == 0;
+    }
+
+    // convert raw values to unsigned format
+    uint32_t mask(int64_t input) const {
+        return static_cast<uint32_t>(input & rawMask());
+    }
+
+    bool decode(uint32_t input, double *output) const {
+        if (output == nullptr) {
+            return false;
+        }
+        int64_t s = signExtendIfNeeded(input);
+        if (s < minRaw || s > maxRaw) {
+            return false;
+        }
+        *output = (s + b) * a;
+        return true;
+    }
+
+    bool encode(double input, uint32_t *output) const {
+        if (output == nullptr) {
+            return false;
+        }
+        input = input / a - b;
+        if (input < minRaw || input > maxRaw) {
+            return false;
+        }
+        *output = static_cast<uint32_t>(static_cast<int64_t>(input) & rawMask());
+        return true;
+    }
+
+    int64_t rawMask() const {
+        constexpr int64_t one = 1;
+        return (one << bitSize) - 1;
+    }
+
+    int64_t signExtendIfNeeded(int64_t value) const {
+        return value | ((isSigned() && isNegative(value)) ? ~rawMask() : 0);
+    }
+
+    bool isNegative(int64_t value) const {
+        constexpr int64_t one = 1;
+        return ((one << (bitSize - 1)) & value) != 0;
+    }
+};
+
+// a collection of report item that forms a packet
+// this is the input output unit with HID hardware
+struct HidParser::ReportPacket {
+    std::vector<ReportItem> reports;
+    size_t bitSize;
+    int type; // REPORT_TYPE_FEATURE/INPUT/OUTPUT
+    unsigned int id;
+
+    size_t getByteSize() const { return (bitSize + 7) / 8; };
+};
+
+std::ostream& operator<<(std::ostream &os, const HidParser::DigestVector &digest2);
+} // namespace HidUtil
+
+#endif // HIDUTIL_HIDPARSER_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidReport.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidReport.cpp
new file mode 100644
index 0000000..9b2b78b
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidReport.cpp
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidReport.h"
+#include "HidDefs.h"
+#include <cmath>
+#include <sstream>
+#include <iomanip>
+
+namespace HidUtil {
+HidReport::HidReport(uint32_t type, uint32_t data,
+                     const HidGlobal &global, const HidLocal &local)
+        : mReportType(type),
+          mFlag(data),
+          mUsagePage(global.usagePage.get(0)),   // default value 0
+          mUsage(local.getUsage(0)),
+          mUsageVector(local.usage),
+          mLogicalMin(global.logicalMin.get(0)), // default value 0
+          mLogicalMax(global.logicalMax.get(0)),
+          mReportSize(global.reportSize),
+          mReportCount(global.reportCount),
+          mPhysicalMin(global.physicalMin),
+          mPhysicalMax(global.physicalMax),
+          mExponent(global.exponent),
+          mUnit(global.unit),
+          mReportId(global.reportId) { }
+
+std::string HidReport::getStringType() const {
+    return reportTypeToString(mReportType);
+}
+
+std::string HidReport::reportTypeToString(int type) {
+    using namespace HidDef::MainTag;
+    switch(type) {
+        case INPUT:
+            return "INPUT";
+        case OUTPUT:
+            return "OUTPUT";
+        case FEATURE:
+            return "FEATURE";
+        default:
+            return "<<UNKNOWN>>";
+    }
+}
+
+double HidReport::getExponentValue() const {
+    if (!mExponent.isSet()) {
+        return 1;
+    }
+    // default exponent is 0
+    int exponentInt = mExponent.get(0);
+    if (exponentInt > 15 || exponentInt < 0) {
+        return NAN;
+    }
+    return pow(10.0, static_cast<double>((exponentInt <= 7) ? exponentInt : exponentInt - 16));
+}
+
+std::string HidReport::getExponentString() const {
+    int exponentInt = mExponent.get(0);
+    if (exponentInt > 15 || exponentInt < 0) {
+        return "[error]";
+    }
+    return std::string("x10^")
+            + std::to_string((exponentInt <= 7) ? exponentInt : exponentInt - 16);
+}
+
+std::string HidReport::getUnitString() const {
+    if (!mUnit.isSet()) {
+        return "default";
+    }
+    return "[not implemented]";
+
+    std::ostringstream ret;
+    ret << std::hex << std::setfill('0') << std::setw(2) << mUnit.get(0);
+    return ret.str();
+}
+
+std::string HidReport::getFlagString() const {
+    using namespace HidDef::ReportFlag;
+    std::string ret;
+    ret += (mFlag & DATA_CONST) ? "Const " : "Data ";
+    ret += (mFlag & ARRAY_VARIABLE) ? "Variable " : "Array ";
+    ret += (mFlag & WRAP) ? "Wrap " : "";
+    ret += (mFlag & NONLINEAR) ? "Nonlinear " : "";
+    ret += (mFlag & NO_PREFERRED) ? "NoPreferred " : "";
+    ret += (mFlag & NULL_STATE) ? "NullState " : "";
+    ret += (mFlag & VOLATILE) ? "Volatile " : "";
+    ret += (mFlag & BUFFERED_BYTES) ? "BufferedBytes " : "";
+    return ret;
+}
+
+// isArray() will return true for reports that may contains multiple values, e.g. keyboard scan
+// code, which can have multiple value, each denoting a key pressed down at the same time. It will
+// return false if repor represent a vector or matrix.
+//
+// This slightly deviates from HID's definition, it is more convenient this way as matrix/vector
+// input is treated similarly as variables.
+bool HidReport::isArray() const {
+    using namespace HidDef::ReportFlag;
+    return (mFlag & ARRAY_VARIABLE) == 0 && mIsCollapsed;
+}
+
+bool HidReport::isVariable() const {
+    return !isArray();
+}
+
+bool HidReport::isData() const {
+    using namespace HidDef::ReportFlag;
+    return (mFlag & DATA_CONST) == 0;
+}
+
+std::ostream& operator<<(std::ostream& os, const HidReport& h) {
+    os << h.getStringType() << ", "
+       << "usage: " << std::hex << h.getFullUsage() << std::dec << ", ";
+
+    if (h.isData()) {
+        auto range = h.getLogicalRange();
+        os << "logMin: " << range.first << ", "
+           << "logMax: " << range.second << ", ";
+
+        if (range == h.getPhysicalRange()) {
+            os << "phy===log, ";
+        } else {
+            range = h.getPhysicalRange();
+            os << "phyMin: " << range.first << ", "
+               << "phyMax: " << range.second << ", ";
+        }
+
+        if (h.isArray()) {
+            os << "map: (" << std::hex;
+            for (auto i : h.getUsageVector()) {
+                os << i << ",";
+            }
+            os << "), " << std::dec;
+        }
+
+        os << "exponent: " << h.getExponentString() << ", "
+           << "unit: " << h.getUnitString() << ", ";
+    } else {
+        os << "constant: ";
+    }
+    os << "size: " << h.getSize() << "bit x " << h.getCount() << ", "
+       << "id: " << h.mReportId;
+
+    return os;
+}
+
+std::pair<int64_t, int64_t> HidReport::getLogicalRange() const {
+    int64_t a = mLogicalMin;
+    int64_t b = mLogicalMax;
+
+    if (a > b) {
+        // might be unsigned
+        a = a & ((static_cast<int64_t>(1) << getSize()) - 1);
+        b = b & ((static_cast<int64_t>(1) << getSize()) - 1);
+        if (a > b) {
+            // bad hid descriptor
+            return {0, 0};
+        }
+    }
+    return {a, b};
+}
+
+std::pair<int64_t, int64_t> HidReport::getPhysicalRange() const {
+    if (!(mPhysicalMin.isSet() && mPhysicalMax.isSet())) {
+        // physical range undefined, use logical range
+        return getLogicalRange();
+    }
+
+    int64_t a = mPhysicalMin.get(0);
+    int64_t b = mPhysicalMax.get(0);
+
+    if (a > b) {
+        a = a & ((static_cast<int64_t>(1) << getSize()) - 1);
+        b = b & ((static_cast<int64_t>(1) << getSize()) - 1);
+        if (a > b) {
+            return {0, 0};
+        }
+    }
+    return {a, b};
+}
+
+unsigned int HidReport::getFullUsage() const {
+    return mUsage | (mUsagePage << 16);
+}
+
+size_t HidReport::getSize() const {
+    return mReportSize;
+}
+
+size_t HidReport::getCount() const {
+    return mReportCount;
+}
+
+unsigned int HidReport::getUnit() const {
+    return mUnit.get(0); // default unit is 0 means default unit
+}
+
+unsigned HidReport::getReportId() const {
+    // if report id is not specified, it defaults to zero
+    return mReportId.get(0);
+}
+
+unsigned HidReport::getType() const {
+    return mReportType;
+}
+
+void HidReport::setCollapsed(uint32_t fullUsage) {
+    mUsage = fullUsage & 0xFFFF;
+    mUsagePage = fullUsage >> 16;
+    mIsCollapsed = true;
+}
+
+const std::vector<unsigned int>& HidReport::getUsageVector() const {
+    return mUsageVector;
+}
+} // namespace HidUtil
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidReport.h b/modules/sensors/dynamic_sensor/HidUtils/HidReport.h
new file mode 100644
index 0000000..9b01b68
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidReport.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDREPORT_H_
+#define HIDUTIL_HIDREPORT_H_
+
+#include "HidGlobal.h"
+#include "HidLocal.h"
+#include "TriState.h"
+#include <cstdint>
+#include <memory>
+#include <iostream>
+#include <utility>
+
+namespace HidUtil {
+
+class HidParser;
+class HidTreeNode;
+
+// HidReport represent an input, output or feature report
+class HidReport {
+    friend std::ostream& operator<<(std::ostream& os, const HidReport& h);
+public:
+    HidReport(uint32_t type_, uint32_t data, const HidGlobal &global, const HidLocal &local);
+
+    // This is called during parsing process when the parser regroups multi-valued report into one
+    void setCollapsed(uint32_t fullUsage);
+
+    // get report id
+    unsigned int getReportId() const;
+    // get type of report, return constant of HidDef::MainTag
+    unsigned int getType() const;
+    // Full sensor usage
+    unsigned int getFullUsage() const;
+
+    // binary properties
+    bool isArray() const;
+    bool isData() const;
+    bool isVariable() const;
+
+    // logical and physical value range
+    std::pair<int64_t, int64_t> getLogicalRange() const;
+    std::pair<int64_t, int64_t> getPhysicalRange() const;
+    double getExponentValue() const;
+
+    // return HID unit nibbles in an unsigned int
+    unsigned int getUnit() const;
+
+    // size in bits
+    size_t getSize() const;
+    // dimension (if it is vector/matrix) or number of concurrent input values
+    // it is also used to calculate memory foot print
+    size_t getCount() const;
+
+    // for output to stream
+    static std::string reportTypeToString(int type);
+    std::string getStringType() const;
+    std::string getExponentString() const;
+    std::string getUnitString() const;
+    std::string getFlagString() const;
+    const std::vector<unsigned int>& getUsageVector() const;
+private:
+    bool mIsCollapsed;
+
+    // mandatary fields
+    unsigned int mReportType;
+    unsigned int mFlag;
+    unsigned int mUsagePage;
+    unsigned int mUsage;
+    std::vector<unsigned int> mUsageVector;
+
+    int mLogicalMin;        // 32 bit is enough
+    int mLogicalMax;
+    unsigned int mReportSize;
+    unsigned int mReportCount;
+
+    // these below are optional
+    tri_int mPhysicalMin;
+    tri_int mPhysicalMax;
+
+    tri_uint mExponent;
+    tri_uint mUnit;
+    tri_uint mReportId;
+};
+
+std::ostream& operator<<(std::ostream& os, const HidReport& h);
+} // namespace HidUtil
+#endif // HIDUTIL_HIDREPORT_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidTree.cpp b/modules/sensors/dynamic_sensor/HidUtils/HidTree.cpp
new file mode 100644
index 0000000..9204135
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidTree.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidDefs.h"
+#include "HidLog.h"
+#include "HidTree.h"
+#include <memory>
+
+namespace HidUtil {
+
+// HidTreeNode
+HidTreeNode::HidTreeNode() : mNodeType(TYPE_UNINITIALIZED), mData(0), mFullUsage(0) {
+}
+
+HidTreeNode::HidTreeNode(std::shared_ptr<HidTreeNode> parent,
+                         uint32_t data, uint32_t fullUsage, int nodeType)
+        : mNodeType(nodeType), mData(data),
+        mFullUsage(fullUsage), mParent(parent) {
+}
+
+HidTreeNode::HidTreeNode(std::shared_ptr<HidTreeNode> parent,
+                         uint32_t data, uint32_t fullUsage)
+        : mNodeType(TYPE_NORMAL), mData(data),
+        mFullUsage(fullUsage), mParent(parent) {
+}
+
+void HidTreeNode::outputRecursive(std::ostream &os, int level) const {
+    insertIndentation(os, level);
+    os << "Node data: " << mData
+       << ", usage " << std::hex << mFullUsage << std::dec << LOG_ENDL;
+
+    for (auto &child : mChildren) {
+        child->outputRecursive(os, level + 1);
+    }
+}
+
+std::shared_ptr<HidTreeNode> HidTreeNode::deepCopy(
+        std::shared_ptr<HidTreeNode> parent) const {
+    std::shared_ptr<HidTreeNode> copy(new HidTreeNode(parent, mData, mFullUsage, mNodeType));
+    for (auto &i : mChildren) {
+        copy->mChildren.push_back(i->deepCopy(copy));
+    }
+    return copy;
+}
+
+void HidTreeNode::insertIndentation(std::ostream &os, int level) const {
+    constexpr char indentCharacter = '\t';
+    std::fill_n(std::ostreambuf_iterator<char>(os), level, indentCharacter);
+}
+
+std::shared_ptr<HidTreeNode> HidTreeNode::addChild(std::shared_ptr<HidTreeNode> child) {
+    mChildren.push_back(child);
+    return child;
+}
+
+std::shared_ptr<HidTreeNode> HidTreeNode::getParent() const {
+    return mParent.lock();
+}
+
+bool HidTreeNode::isReportCollection() const {
+    return mNodeType == TYPE_NORMAL && mChildren.size() == 1
+            && mChildren.front()->mNodeType == TYPE_REPORT;
+}
+
+unsigned int HidTreeNode::getFullUsage() const {
+    return mFullUsage;
+}
+
+std::vector<std::shared_ptr<HidTreeNode>>& HidTreeNode::getChildren() {
+    return mChildren;
+}
+
+const std::vector<std::shared_ptr<HidTreeNode>>& HidTreeNode::getChildren() const {
+    return mChildren;
+}
+
+bool HidTreeNode::isUsageCollection() const {
+    using namespace HidDef::CollectionType;
+    return mNodeType == TYPE_NORMAL && (mData == PHYSICAL || mData == APPLICATION);
+}
+
+int HidTreeNode::getNodeType() const {
+    return mNodeType;
+}
+
+std::ostream& operator<<(std::ostream& os, const HidTreeNode& n) {
+    n.outputRecursive(os, 0);
+    return os;
+}
+
+// HidReportNode
+HidReportNode::HidReportNode(std::shared_ptr<HidTreeNode> parent, const HidReport &report)
+    : HidTreeNode(parent, 0 /*data*/, 0 /*fullUsage*/, TYPE_REPORT), mReport(report) {
+}
+
+void HidReportNode::outputRecursive(std::ostream &os, int level) const {
+    insertIndentation(os, level);
+    os << mReport << LOG_ENDL;
+}
+
+std::shared_ptr<HidTreeNode> HidReportNode::deepCopy(
+        std::shared_ptr<HidTreeNode> parent) const {
+    std::shared_ptr<HidTreeNode> copy(new HidReportNode(parent, mReport));
+    return copy;
+}
+
+const HidReport& HidReportNode::getReport() const {
+    return mReport;
+}
+
+void HidReportNode::collapse(unsigned int newUsage) {
+    mReport.setCollapsed(newUsage);
+}
+
+} //namespace HidUtil
diff --git a/modules/sensors/dynamic_sensor/HidUtils/HidTree.h b/modules/sensors/dynamic_sensor/HidUtils/HidTree.h
new file mode 100644
index 0000000..2752007
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/HidTree.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_HIDTREE_H_
+#define HIDUTIL_HIDTREE_H_
+
+#include "HidReport.h"
+
+#include <cstddef>
+#include <vector>
+#include <iostream>
+
+namespace HidUtil {
+
+// HID report parser output tree node
+class HidTreeNode {
+    friend std::ostream& operator<<(std::ostream& os, const HidTreeNode& n);
+public:
+    enum {
+        TYPE_UNINITIALIZED = 0,
+        TYPE_NORMAL = 1,
+        TYPE_REPORT = 2     // can be cast to HidReportNode
+    };
+    HidTreeNode();
+    HidTreeNode(std::shared_ptr<HidTreeNode> parent, uint32_t data, uint32_t fullUsage);
+
+    virtual ~HidTreeNode() = default;
+
+    // make a deep copy of tree at and below this node and attach it to specified parent node
+    virtual std::shared_ptr<HidTreeNode> deepCopy(
+          std::shared_ptr<HidTreeNode> parent = nullptr) const;
+
+    // add child to this node
+    std::shared_ptr<HidTreeNode> addChild(std::shared_ptr<HidTreeNode> child);
+
+    // get all children of a node
+    std::vector<std::shared_ptr<HidTreeNode>>& getChildren();
+    const std::vector<std::shared_ptr<HidTreeNode>>& getChildren() const;
+
+    // get parent (nullptr if it is root node or if lock weak_ptr failed)
+    std::shared_ptr<HidTreeNode> getParent() const;
+
+    // access usage of this node
+    unsigned int getFullUsage() const;
+
+    bool isReportCollection() const;
+    bool isUsageCollection() const;
+    int getNodeType() const;
+protected:
+    // for derived class to define different nodeType
+    HidTreeNode(std::shared_ptr<HidTreeNode> parent,
+              uint32_t data, uint32_t fullUsage, int nodeType);
+
+    // helper for stream output
+    void insertIndentation(std::ostream &os, int level) const;
+private:
+    // helper for stream output
+    virtual void outputRecursive(std::ostream& os, int level) const;
+
+    int mNodeType;
+    uint32_t mData;
+    uint32_t mFullUsage;
+
+    std::vector<std::shared_ptr<HidTreeNode>> mChildren;
+    std::weak_ptr<HidTreeNode> mParent;
+};
+
+// Tree node that corresponds to an input, output or feature report
+class HidReportNode : public HidTreeNode {
+public:
+    HidReportNode(std::shared_ptr<HidTreeNode> parent, const HidReport &report);
+
+    virtual std::shared_ptr<HidTreeNode> deepCopy(
+          std::shared_ptr<HidTreeNode> parent = nullptr) const override;
+
+    // obtain HidReport attached to this node
+    const HidReport& getReport() const;
+
+    // reset usage of node and set underlying report to collapsed
+    void collapse(unsigned int newUsage);
+private:
+    virtual void outputRecursive(std::ostream &os, int level) const override;
+
+    HidReport mReport;
+};
+
+std::ostream& operator<<(std::ostream& os, const HidTreeNode& n);
+
+} // namespace HidUtil
+
+#endif // HIDUTIL_HIDTREE_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/StreamIoUtil.h b/modules/sensors/dynamic_sensor/HidUtils/StreamIoUtil.h
new file mode 100644
index 0000000..45a94b6
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/StreamIoUtil.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_STREAM_IO_UTIL_H_
+#define HIDUTIL_STREAM_IO_UTIL_H_
+
+#include "HidLog.h"
+#include <istream>
+#include <iomanip>
+#include <sstream>
+#include <vector>
+#include <cassert>
+
+namespace HidUtil {
+
+template<typename CharT>
+class charvectorbuf : public std::streambuf { // class name is consistent with std lib
+    static_assert(std::is_const<CharT>::value == false, "cannot use const type");
+public:
+    // r/w buffer constructors
+    charvectorbuf(std::vector<CharT> &vec) {
+        init(vec.data(), vec.size());
+    }
+
+    charvectorbuf(CharT *begin, CharT *end) {
+        assert(end >= begin);
+        init(begin, end - begin);
+    }
+
+    charvectorbuf(CharT *begin, size_t size) {
+        init(begin, size);
+    }
+
+    // r/o buffer constructor
+    charvectorbuf(const std::vector<CharT> &vec) {
+        init(vec.data(), vec.size());
+    }
+
+    charvectorbuf(const CharT *begin, const CharT *end) {
+        assert(end >= begin);
+        init(begin, end - begin);
+    }
+
+    charvectorbuf(const CharT *begin, size_t size) {
+        init(begin, size);
+    }
+ protected:
+    virtual std::streampos seekpos(
+            std::streampos sp, std::ios_base::openmode which =
+            std::ios_base::in | std::ios_base::out) override {
+        return seekoff(std::streamoff(sp), std::ios_base::beg, which);
+    }
+
+    // this is needed to use ftell() on stream
+    virtual std::streampos seekoff(
+            std::streamoff off, std::ios_base::seekdir way,
+            std::ios_base::openmode which =
+            std::ios_base::in | std::ios_base::out) override {
+
+        // pptr() == nullptr: read-only
+        assert(pptr() == nullptr || egptr() - eback() == epptr() - pbase());
+        bool in = which & std::ios_base::in;
+        bool out = which & std::ios_base::out;
+        pos_type end = egptr() - eback();
+
+        if (!in && !out) {
+            return pos_type(-1);
+        }
+
+        if (in && out && way == std::ios_base::cur) {
+            return pos_type(-1);
+        }
+
+        off_type noff;
+        switch (way) {
+            case std::ios_base::beg:
+                noff = 0;
+                break;
+            case std::ios_base::cur:
+                if (in) {
+                    noff = gptr() - eback();
+                } else {
+                    noff = pptr() - pbase();
+                }
+                break;
+            case std::ios_base::end:
+                noff = end;
+                break;
+            default:
+                return pos_type(-1);
+        }
+        noff += off;
+        if (noff < 0 ||  noff > end) {
+            return pos_type(-1);
+        }
+
+        if (noff != 0 && ((in && gptr() == nullptr) || (out && pptr() == nullptr))) {
+            return pos_type(-1);
+        }
+
+        if (in) {
+            setg(eback(), eback() + noff, egptr());
+        }
+
+        if (out) {
+            setp(pbase(), epptr());
+            pbump(noff);
+        }
+
+        return pos_type(noff);
+    }
+private:
+    // read only buffer init
+    void init(const CharT *base, size_t size) {
+        setg((char*)base, (char*)base, (char*)(base + size));
+    }
+
+    // read write buffer init
+    void init(CharT *base, size_t size) {
+        setg((char*)base, (char*)base, (char*)(base + size));
+        setp((char*)base, (char*)(base + size));
+    }
+};
+
+// dump binary values
+template <class ForwardIterator>
+void hexdumpToStream(std::ostream &os, const ForwardIterator &first, const ForwardIterator &last) {
+    static_assert(
+            std::is_convertible<
+                typename std::iterator_traits<ForwardIterator>::iterator_category,
+                std::forward_iterator_tag>::value
+            && std::is_convertible<
+                typename std::iterator_traits<ForwardIterator>::value_type,
+                unsigned char>::value
+            && sizeof(typename std::iterator_traits<ForwardIterator>::value_type)
+                == sizeof(unsigned char),
+            "Only accepts forward iterator of a type of size 1 "
+                "that can be convert to unsigned char.\n");
+    size_t c = 0;
+    std::ostringstream ss;
+    for (ForwardIterator i = first; i != last; ++i, ++c) {
+        unsigned char v = *i;
+        // formatting
+        switch (c & 0xf) {
+            case 0:
+                // address
+                os << ss.str() << LOG_ENDL;
+                ss.str("");
+                ss << std::hex;
+                ss << std::setfill('0') << std::setw(4) << c << ": ";
+                break;
+            case 8:
+                // space
+                ss << " ";
+                break;
+        }
+        ss << std::setfill('0') << std::setw(2)
+           << static_cast<unsigned>(static_cast<unsigned char>(v)) << " ";
+    }
+    os << ss.str() << LOG_ENDL;
+}
+} //namespace HidUtil
+
+#endif // HIDUTIL_STREAM_IO_UTIL_H_
+
diff --git a/modules/sensors/dynamic_sensor/HidUtils/TriState.h b/modules/sensors/dynamic_sensor/HidUtils/TriState.h
new file mode 100644
index 0000000..1e44826
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/TriState.h
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_TRISTATE_H_
+#define HIDUTIL_TRISTATE_H_
+
+#include <cassert>
+#include <iostream>
+
+namespace HidUtil {
+template<typename T>
+class TriState {
+public:
+    // constructor
+    TriState() : mIsSet(false) { }
+    TriState(const TriState<T> &other) : mIsSet(other.mIsSet), mValue(other.mValue) { }
+    explicit TriState(const T &value) : mIsSet(true), mValue(value) { }
+
+    void clear() {
+        mValue = T();
+        mIsSet = false;
+    }
+    bool isSet() const {
+        return mIsSet;
+    }
+
+    const T get(const T &defaultValue) const {
+        return isSet() ? mValue : defaultValue;
+    }
+
+    // operator overloading
+    explicit operator T () const {
+        assert(mIsSet);
+        return mValue;
+    }
+
+    TriState<T>& operator=(const TriState<T> &other) {
+        mIsSet = other.mIsSet;
+        mValue = other.mValue;
+        return *this;
+    }
+
+    TriState<T>& operator=(const T& value) {
+        mIsSet = true;
+        mValue = value;
+        return *this;
+    }
+
+    TriState<T>& operator++()  {
+        if (mIsSet) {
+            mValue++;
+        }
+        return *this;
+    }
+
+    TriState<T> operator++(int) {
+        TriState<T> tmp(*this);
+        operator++();
+        return tmp;
+    }
+
+    TriState<T>& operator--()  {
+        if (mIsSet) {
+            mValue--;
+        }
+        return *this;
+    }
+
+    TriState<T> operator--(int) {
+        TriState<T> tmp(*this);
+        operator--();
+        return tmp;
+    }
+
+#define UNARY_OP(op) \
+    TriState<T> operator op() { \
+        TriState<T> tmp(*this); \
+        if (mIsSet) { \
+            tmp.mValue = op tmp.mValue; \
+        } \
+        return tmp; \
+    }
+
+    UNARY_OP(!);
+    UNARY_OP(-);
+    UNARY_OP(~);
+#undef UNARY_OP
+
+#define COMPOUND_ASSIGN_OP(op) \
+    TriState<T>& operator op (const TriState<T>& rhs) { \
+        if (mIsSet && rhs.mIsSet) { \
+            mValue op rhs.mValue; \
+        } else { \
+            mIsSet = false; \
+        } \
+        return *this; \
+    } \
+    TriState<T>& operator op(const T& rhs) { \
+        if (mIsSet) { \
+            mValue op rhs; \
+        } \
+        return *this; \
+    }
+
+    COMPOUND_ASSIGN_OP(+=);
+    COMPOUND_ASSIGN_OP(-=);
+    COMPOUND_ASSIGN_OP(*=);
+    COMPOUND_ASSIGN_OP(/=);
+    COMPOUND_ASSIGN_OP(%=);
+    COMPOUND_ASSIGN_OP(&=);
+    COMPOUND_ASSIGN_OP(|=);
+    COMPOUND_ASSIGN_OP(^=);
+#undef COMPOUND_ASSIGN_OP
+
+    TriState<T>& operator >>=(int i) {
+        if (mIsSet) {
+            mValue >>= i;
+        }
+        return *this; \
+    }
+
+    TriState<T>& operator <<=(int i) {
+        if (mIsSet) {
+            mValue <<= i;
+        }
+        return *this; \
+    }
+
+    TriState<T> operator <<(int i) { \
+        TriState<T> tmp(*this);
+        operator<<(i);
+        return tmp;
+    }
+
+    TriState<T> operator >>(int i) { \
+        TriState<T> tmp(*this);
+        operator>>(i);
+        return tmp;
+    }
+
+#define BINARY_OP(op, compound_op) \
+    friend TriState<T> operator op(TriState<T> lhs, const TriState<T>& rhs) { \
+        lhs compound_op rhs; \
+    return lhs; \
+    }\
+        friend TriState<T> operator op(TriState<T> lhs, const T& rhs) { \
+    lhs compound_op rhs; \
+        return lhs; \
+    }\
+    friend TriState<T> operator op(const T &lhs, const TriState<T>& rhs) { \
+        TriState<T> tmp(lhs); \
+        return tmp op rhs; \
+    }
+
+    BINARY_OP(+, +=);
+    BINARY_OP(-, -=);
+    BINARY_OP(*, *=);
+    BINARY_OP(/, /=);
+    BINARY_OP(%, %=);
+    BINARY_OP(&, &=);
+    BINARY_OP(|, |=);
+    BINARY_OP(^, ^=);
+#undef BINARY_OP
+
+#define RELATION_OP(op) \
+    friend TriState<bool> operator op(const TriState<T>& lhs, const TriState<T>& rhs) { \
+        if (lhs.mIsSet && rhs.mIsSet) { \
+            return TriState<bool>(lhs.mValue op rhs.mValue); \
+        } else { \
+        return TriState<bool>(); \
+        } \
+    } \
+    friend TriState<bool> operator op(const TriState<T>& lhs, const T& rhs) { \
+        if (lhs.mIsSet) { \
+            return TriState<bool>(lhs.mValue op rhs); \
+        } else { \
+            return TriState<bool>(); \
+        } \
+    } \
+    friend TriState<bool> operator op(const T& lhs, const TriState<T>& rhs) { \
+        if (rhs.mIsSet) { \
+            return TriState<bool>(lhs op rhs.mValue); \
+        } else { \
+            return TriState<bool>(); \
+        } \
+    }
+
+    RELATION_OP(==);
+    RELATION_OP(!=);
+    RELATION_OP(>=);
+    RELATION_OP(<=);
+    RELATION_OP(>);
+    RELATION_OP(<);
+#undef RELATION_OP
+
+    friend TriState<bool> operator &&(TriState<T>& lhs, const TriState<T>& rhs) {
+        if (lhs.mIsSet && rhs.mIsSet) {
+            return TriState<bool>(lhs.mValue && rhs.mValue);
+        } else {
+            return TriState<bool>();
+        }
+    }
+
+    friend TriState<bool> operator ||(TriState<T>& lhs, const TriState<T>& rhs) {
+        if (lhs.mIsSet && rhs.mIsSet) {
+            return TriState<bool>(lhs.mValue || rhs.mValue);
+        } else {
+            return TriState<bool>();
+        }
+    }
+
+    friend std::ostream& operator <<(std::ostream &os, const TriState<T> &v) {
+        if (v.mIsSet) {
+            os << v.mValue;
+        } else {
+            os << "[not set]";
+        }
+        return os;
+    }
+
+    friend std::istream& operator >>(std::istream &is, const TriState<T> &v) {
+        T a;
+        is >> a;
+        v = TriState<T>(a);
+        return is;
+    }
+private:
+    bool mIsSet;
+    T mValue;
+};
+
+// commonly used ones
+typedef TriState<unsigned> tri_uint;
+typedef TriState<int> tri_int;
+
+typedef TriState<uint32_t> tri_uint32_t;
+typedef TriState<int32_t> tri_int32_t;
+typedef TriState<uint8_t> tri_uint8_t;
+typedef TriState<uint16_t> tri_uint16_t;
+}
+
+#endif // HIDUTIL_TRISTATE_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/test/HidParserExample.cpp b/modules/sensors/dynamic_sensor/HidUtils/test/HidParserExample.cpp
new file mode 100644
index 0000000..ec7243e
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/test/HidParserExample.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "HidLog.h"
+#include "HidParser.h"
+#include "TestHidDescriptor.h"
+#include <errno.h>
+
+using HidUtil::HidParser;
+
+bool doParse() {
+    HidParser hidParser;
+    bool ret = true;
+
+    for (const TestHidDescriptor *p = gDescriptorArray; ; ++p) {
+        if (p->data == nullptr || p->len == 0) {
+            break;
+        }
+        const char *name = p->name != nullptr ? p->name : "unnamed";
+        bool parseResult = hidParser.parse(p->data, p->len);
+
+        if (parseResult) {
+            LOG_V << name << "  filtered tree: " << LOG_ENDL;
+            LOG_V << *(hidParser.getTree());
+        } else {
+            ret = false;
+            LOG_E << name << " parsing error!" << LOG_ENDL;
+        }
+    }
+    return ret;
+}
+
+bool doParseAndFilter() {
+    HidParser hidParser;
+    bool ret = true;
+
+    for (const TestHidDescriptor *p = gDescriptorArray; ; ++p) {
+        if (p->data == nullptr || p->len == 0) {
+            break;
+        }
+        const char *name = p->name != nullptr ? p->name : "unnamed";
+        bool parseResult = hidParser.parse(p->data, p->len);
+
+        if (parseResult) {
+            hidParser.filterTree();
+            LOG_V << name << "  filtered tree: " << LOG_ENDL;
+            LOG_V << *(hidParser.getTree());
+        } else {
+            ret = false;
+            LOG_E << name << " parsing error!" << LOG_ENDL;
+        }
+    }
+    return ret;
+}
+
+bool doDigest() {
+    HidParser hidParser;
+    bool ret = true;
+
+    // value from HID sensor usage page spec
+    std::unordered_set<unsigned int> interestedUsage = {
+        0x200073, // accelerometer 3d
+        0x200076, // gyro 3d
+        0x200083, // mag 3d
+        0x20008a, // device orientation (rotation vector)
+    };
+
+    for (const TestHidDescriptor *p = gDescriptorArray; ; ++p) {
+        if (p->data == nullptr || p->len == 0) {
+            break;
+        }
+        const char *name = p->name != nullptr ? p->name : "unnamed";
+        bool parseResult = hidParser.parse(p->data, p->len);
+
+        if (!parseResult) {
+            LOG_E << name << " parsing error!" << LOG_ENDL;
+            ret = false;
+            continue;
+        }
+
+        hidParser.filterTree();
+        LOG_V << name << "  digest: " << LOG_ENDL;
+        HidParser::DigestVector digestVector = hidParser.generateDigest(interestedUsage);
+        LOG_V << digestVector;
+    }
+    return ret;
+}
+
+void printUsage(char *argv0) {
+    LOG_V << "Usage: " << argv0 << " test_name" << LOG_ENDL;
+    LOG_V << "  test_name can be parse, parse_filter, digest." << LOG_ENDL;
+}
+
+int main(int argc, char* argv[]) {
+    int ret;
+
+    if (argc != 2) {
+        LOG_E << "Error: need param" << LOG_ENDL;
+        printUsage(argv[0]);
+        return -EINVAL;
+    }
+
+    if (strcmp(argv[1], "parse") == 0) {
+        ret = doParse() ? 0 : 1;
+    } else if (strcmp(argv[1], "parse_filter") == 0) {
+        ret = doParseAndFilter() ? 0 : 1;
+    } else if (strcmp(argv[1], "digest") == 0) {
+        ret = doDigest() ? 0 : 1;
+    } else {
+        LOG_E << "Error: unknown test name" << LOG_ENDL;
+        printUsage(argv[0]);
+        ret = -ENOENT;
+    }
+
+    return ret;
+}
diff --git a/modules/sensors/dynamic_sensor/HidUtils/test/HidParserExample2.cpp b/modules/sensors/dynamic_sensor/HidUtils/test/HidParserExample2.cpp
new file mode 100644
index 0000000..b151dff
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/test/HidParserExample2.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "TestHidDescriptor.h"
+#include "HidLog.h"
+#include "HidParser.h"
+#include "StreamIoUtil.h"
+
+using namespace HidUtil;
+
+void printRawValue(const std::vector<unsigned char> &descriptor) {
+    LOG_D << "Descriptor [" << descriptor.size() << "]: " << std::hex;
+    hexdumpToStream(LOG_D, descriptor.begin(), descriptor.end());
+}
+
+void printToken(const std::vector<HidItem> &hidItemVector) {
+    LOG_V << "Total " << hidItemVector.size() << " tokens" << LOG_ENDL;
+    for (auto &i : hidItemVector) {
+        LOG_V << i << LOG_ENDL;
+    }
+}
+
+int main() {
+    const TestHidDescriptor *t = findTestDescriptor("accel3");
+    constexpr unsigned int ACCEL_3D_USAGE = 0x200073;
+
+    assert(t != nullptr);
+    std::vector<unsigned char> descriptor(t->data, t->data + t->len);
+
+    // parse can be done in one step with HidParser::parse(const unsigned char *begin, size_t size);
+    // here it is done in multiple steps for illustration purpose
+    HidParser hidParser;
+    // print out raw value
+    printRawValue(descriptor);
+
+    // tokenize it
+    std::vector<HidItem> hidItemVector = HidItem::tokenize(descriptor);
+
+    // print out tokens
+    printToken(hidItemVector);
+
+    // parse it
+    if (hidParser.parse(hidItemVector)) {
+        // making a deepcopy of tree (not necessary, but for illustration)
+        std::shared_ptr<HidTreeNode> tree = hidParser.getTree()->deepCopy();
+
+        LOG_V << "Tree: " << LOG_ENDL;
+        LOG_V << *tree;
+        LOG_V << LOG_ENDL;
+
+        hidParser.filterTree();
+        LOG_V << "FilteredTree: " << LOG_ENDL;
+        LOG_V << *(hidParser.getTree());
+
+        LOG_V << "DigestVector: " << LOG_ENDL;
+        std::unordered_set<unsigned int> interested = {ACCEL_3D_USAGE};
+        HidParser::DigestVector digestVector = hidParser.generateDigest(interested);
+        LOG_V << digestVector;
+
+    } else {
+        LOG_V << "Parsing Error" << LOG_ENDL;
+    }
+
+    return 0;
+}
+
diff --git a/modules/sensors/dynamic_sensor/HidUtils/test/TestHidDescriptor.cpp b/modules/sensors/dynamic_sensor/HidUtils/test/TestHidDescriptor.cpp
new file mode 100644
index 0000000..ac57d4f
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/test/TestHidDescriptor.cpp
@@ -0,0 +1,2607 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "TestHidDescriptor.h"
+#include "TestHidSensorSpec.h"
+#include <cstring>
+
+/**
+ * Example HID sensor descriptors in this file is extracted from published document
+ * "HID Sensors Usage" (hid-sensors-usage.docx). They are added for testing of HidParser.
+ *
+ * It is slightly modified in order to compile.
+ */
+namespace {
+/**
+ * Two sensors collection skeleton example.
+ */
+const unsigned char col1_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_COLLECTION,
+    HID_COLLECTION(Application),
+
+    HID_REPORT_ID(1),
+    HID_USAGE_PAGE_SENSOR,
+
+    HID_USAGE_SENSOR_TYPE_MOTION_ACCELEROMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //Feature Report Descriptor for Sensor Report ID = 1
+
+    //Input Report Descriptor for Sensor Report ID = 1
+
+    HID_END_COLLECTION, //for Report ID = 1
+
+    HID_REPORT_ID(2),
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //Feature Report Descriptor for Sensor Report ID = 2
+
+    //Input Report Descriptor for Sensor Report ID = 2
+
+    HID_END_COLLECTION, //for Report ID = 2
+
+    //More sensors follow using the same pattern
+
+    HID_END_COLLECTION //Application
+};
+
+
+/**
+ * Composite device descriptor example: two sensors with a keyboard and a mouse.
+ */
+const unsigned char col2_report_descriptor[] = {
+    //keyboard
+    0x05U, 0x01U,         // USAGE PAGE (Generic Desktop)
+    0x09U, 0x06U,         // USAGE (Keyboard)
+    0xA1U, 0x01U,         // COLLECTION (Application)
+
+    0x85U, 0x03U,         // REPORT_ID (1)
+
+    0x15U, 0x00U,         //   LOGICAL MINIMUM (0)
+    0x25U, 0x01U,         //   LOGICAL MAXIMUM (1)
+    0x75U, 0x01U,         //   REPORT SIZE (1)
+    0x95U, 0x08U,         //   REPORT COUNT (8)
+    0x05U, 0x07U,         //   USAGE PAGE (Keyboard)
+    0x19U, 0xE0U,         //   USAGE MINIMUM (Keyboard LeftControl)
+    0x29U, 0xE7U,         //   USAGE MAXIMUM (Keyboard Right GUI)
+    0x81U, 0x02U,         //   INPUT (Var)
+
+    0x75U, 0x08U,         //   REPORT SIZE (8)
+    0x95U, 0x0AU,         //   REPORT COUNT (10)
+    0x19U, 0x00U,         //   USAGE MINIMUM (No event)
+    0x29U, 0x91U,         //   USAGE MAXIMUM (Keyboard LANG2)
+    0x26U, 0xFFU, 0x00U,  //   LOGICAL MAXIMUM (0xFF)
+    0x81U, 0x00U,         //   INPUT (Data,Ary,Abs)
+
+    0xC0U,                // END COLLECTION, //keyboard
+
+    // Two sensor collection skeleton example:
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_COLLECTION,
+    HID_COLLECTION(Application),
+
+    HID_REPORT_ID(2),
+    HID_USAGE_PAGE_SENSOR,
+
+    HID_USAGE_SENSOR_TYPE_MOTION_ACCELEROMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //Feature Report Descriptor for Sensor Report ID = 2
+
+    //Input Report Descriptor for Sensor Report ID = 2
+
+    HID_END_COLLECTION, //for Report ID = 2
+
+    HID_REPORT_ID(3),
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //Feature Report Descriptor for Sensor Report ID = 3
+
+    //Input Report Descriptor for Sensor Report ID = 3
+
+    HID_END_COLLECTION, //for Report ID = 3
+
+    //More sensors follow using the same pattern
+
+    HID_END_COLLECTION, //Sensor collection
+
+    //mouse
+    0x05U, 0x01U,         // USAGE PAGE (Generic Desktop)
+    0x09U, 0x02U,         // USAGE (Mouse)
+    0xA1U, 0x01U,         // COLLECTION (Application)
+    0x85U, 0x04U,         // REPORT_ID (4)
+
+    // 5 mouse buttons
+    0x05U, 0x09U,         //   USAGE PAGE (Button)
+    0x19U, 0x01U,         //   USAGE MINIMUM (Button 1)
+    0x29U, 0x05U,         //   USAGE MAXIMUM (Button 5)
+    0x15U, 0x00U,         //   LOGICAL MINIMUM (0)
+    0x25U, 0x01U,         //   LOGICAL MAXIMUM (1)
+    0x95U, 0x05U,         //   REPORT COUNT (5)
+    0x75U, 0x01U,         //   REPORT SIZE (1)
+    0x81U, 0x02U,         //   INPUT (Data,Var,Abs)
+
+    //  3 unused buttons:
+    0x95U, 0x01U,         //   REPORT COUNT (1)
+    0x75U, 0x03U,         //   REPORT SIZE (3)
+    0x81U, 0x03U,         //   INPUT (Cnst,Var,Abs)
+
+    // mouse (delta x, delta y) position
+    0x15U, 0x81U,         //   LOGICAL MINIMUM (-127)
+    0x25U, 0x7fU,         //   LOGICAL MAXIMUM (+127)
+    0x75U, 0x08U,         //   REPORT SIZE (8)
+    0x95U, 0x02U,         //   REPORT COUNT (2)
+    0x05U, 0x01U,         //   USAGE PAGE (Generic Desktop)
+    0x09U, 0x30U,         //   USAGE(X)
+    0x09U, 0x31U,         //   USAGE (Y)
+    0x81U, 0x06U,         //   INPUT (Data,Var,Rel)
+
+    0xC0U,                // END COLLECTION //mouse
+};
+
+
+/**
+ * Composite device descriptor example: one sensor with a keyboard and a mouse.
+ */
+const unsigned char col3_report_descriptor[] = {
+    //keyboard
+    0x05U, 0x01U,         // USAGE PAGE (Generic Desktop)
+    0x09U, 0x06U,         // USAGE (Keyboard)
+    0xA1U, 0x01U,         // COLLECTION (Application)
+
+    0x85U, 0x03U,         // REPORT_ID (1)
+
+    0x15U, 0x00U,         //   LOGICAL MINIMUM (0)
+    0x25U, 0x01U,         //   LOGICAL MAXIMUM (1)
+    0x75U, 0x01U,         //   REPORT SIZE (1)
+    0x95U, 0x08U,         //   REPORT COUNT (8)
+    0x05U, 0x07U,         //   USAGE PAGE (Keyboard)
+    0x19U, 0xE0U,         //   USAGE MINIMUM (Keyboard LeftControl)
+    0x29U, 0xE7U,         //   USAGE MAXIMUM (Keyboard Right GUI)
+    0x81U, 0x02U,         //   INPUT (Var)
+
+    0x75U, 0x08U,         //   REPORT SIZE (8)
+    0x95U, 0x0AU,         //   REPORT COUNT (10)
+    0x19U, 0x00U,         //   USAGE MINIMUM (No event)
+    0x29U, 0x91U,         //   USAGE MAXIMUM (Keyboard LANG2)
+    0x26U, 0xFFU, 0x00U,  //   LOGICAL MAXIMUM (0xFF)
+    0x81U, 0x00U,         //   INPUT (Data,Ary,Abs)
+
+    0xC0U,                // END COLLECTION, //keyboard
+
+    // One sensor collection skeleton example:
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_COLLECTION,
+    HID_COLLECTION(Application),
+
+    HID_REPORT_ID(2),
+    HID_USAGE_PAGE_SENSOR,
+
+    HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //Feature Report Descriptor for Sensor Report ID = 2
+
+    //Input Report Descriptor for Sensor Report ID = 2
+
+    HID_END_COLLECTION, //for Report ID = 2
+
+    HID_END_COLLECTION, //Sensor collection
+
+    //mouse
+    0x05U, 0x01U,         // USAGE PAGE (Generic Desktop)
+    0x09U, 0x02U,         // USAGE (Mouse)
+    0xA1U, 0x01U,         // COLLECTION (Application)
+    0x85U, 0x04U,         // REPORT_ID (3)
+
+    // 5 mouse buttons
+    0x05U, 0x09U,         //   USAGE PAGE (Button)
+    0x19U, 0x01U,         //   USAGE MINIMUM (Button 1)
+    0x29U, 0x05U,         //   USAGE MAXIMUM (Button 5)
+    0x15U, 0x00U,         //   LOGICAL MINIMUM (0)
+    0x25U, 0x01U,         //   LOGICAL MAXIMUM (1)
+    0x95U, 0x05U,         //   REPORT COUNT (5)
+    0x75U, 0x01U,         //   REPORT SIZE (1)
+    0x81U, 0x02U,         //   INPUT (Data,Var,Abs)
+
+    //  3 unused buttons:
+    0x95U, 0x01U,         //   REPORT COUNT (1)
+    0x75U, 0x03U,         //   REPORT SIZE (3)
+    0x81U, 0x03U,         //   INPUT (Cnst,Var,Abs)
+
+    // mouse (delta x, delta y) position
+    0x15U, 0x81U,         //   LOGICAL MINIMUM (-127)
+    0x25U, 0x7fU,         //   LOGICAL MAXIMUM (+127)
+    0x75U, 0x08U,         //   REPORT SIZE (8)
+    0x95U, 0x02U,         //   REPORT COUNT (2)
+    0x05U, 0x01U,         //   USAGE PAGE (Generic Desktop)
+    0x09U, 0x30U,         //   USAGE(X)
+    0x09U, 0x31U,         //   USAGE (Y)
+    0x81U, 0x06U,         //   INPUT (Data,Var,Rel)
+
+    0xC0U,                 //   END COLLECTION //mouse
+};
+
+
+/**
+ * Simple custom sensor example.
+ */
+const unsigned char cus1_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,         // USAGE_PAGE (Sensor)
+    HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM, // USAGE (Simple Custom)
+    HID_COLLECTION(Physical),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * More complex custom sensor example.
+ */
+const unsigned char cus2_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,         // USAGE_PAGE (Sensor)
+    HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM, // USAGE (Simple Custom)
+    HID_COLLECTION(Physical),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_DATA_CUSTOM_USAGE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_TYPE_MOTION_SPEEDOMETER
+    HID_USAGE_SENSOR_DATA_CUSTOM_BOOLEAN_ARRAY,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_TYPE_MOTION_SPEEDOMETER
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_2,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_3,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_4,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_5,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_6,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Custom sensor example with features
+ */
+const unsigned char cus3_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,         // USAGE_PAGE (Sensor)
+    HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM, // USAGE (Simple Custom)
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_CUSTOM,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_CUSTOM,HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_CUSTOM,HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_CUSTOM_USAGE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_TYPE_MOTION_SPEEDOMETER
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs), // = HID_USAGE_SENSOR_DATA_MOTION_SPEED value
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Full custom sensor example with feature.
+ */
+const unsigned char cus4_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,         // USAGE_PAGE (Sensor)
+    HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM, // USAGE (Simple Custom)
+    HID_COLLECTION(Application),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_CUSTOM,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_CUSTOM,HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_CUSTOM,HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_CUSTOM_USAGE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_BOOLEAN_ARRAY,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_2,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_3,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_4,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_5,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_6,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+
+#if 1 //define vendor-specific (non-spec) custom datafields
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_7,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_8,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_9,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_10,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_11,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_12,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_13,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_14,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_15,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_16,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_17,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_18,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_19,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_20,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_21,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_22,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_23,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_24,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_25,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_26,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_27,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_28,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale unit to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+#endif
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Human presence sensor example.
+ */
+const unsigned char pres_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_BIOMETRIC_PRESENCE,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PRESENCE,
+    HID_LOGICAL_MIN_8(0), // False
+    HID_LOGICAL_MAX_8(1), // True
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Proximity sensor example.
+ */
+const unsigned char prox_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_BIOMETRIC_PROXIMITY,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PROXIMITY_RANGE,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0D), // scale default unit "meter" to "centimeter"
+    // to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PROXIMITY_RANGE,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0D), // scale default unit "meter" to "centimeter"
+    // to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PROXIMITY_RANGE,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0D), // scale default unit "meter" to "centimeter"
+    // to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PROXIMITY_OUT_OF_RANGE,
+    HID_LOGICAL_MIN_8(0), // False
+    HID_LOGICAL_MAX_8(1), // True
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PROXIMITY_RANGE,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0D),  // scale default unit "meter" to "centimeter"
+    // to provide 2 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Barometer sensor example.
+ */
+const unsigned char bar_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_ATMOSPHERIC_PRESSURE,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_ATMOSPHERIC_PRESSURE,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Bar" to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_ATMOSPHERIC_PRESSURE,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Bar" to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_ATMOSPHERIC_PRESSURE,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Bar" to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_ATMOSPHERIC_PRESSURE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Bar" to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Humidity sensor example.
+ */
+const unsigned char humi_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_HUMIDITY,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_RELATIVE_HUMIDITY,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0x10,0x27), // 10000 = 0.00 to 100.00 percent with 2 digits past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_RELATIVE_HUMIDITY,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0x10,0x27), // 10000 = 0.00 to 100.00 percent with 2 digits past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_RELATIVE_HUMIDITY,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0x10,0x27), // 10000 = 0.00 to 100.00 percent with 2 digits past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_RELATIVE_HUMIDITY,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0x10,0x27), // 10000 = 0.00 to 100.00 percent with 2 digits past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "percent"
+    // to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Temperature sensor example.
+ */
+const unsigned char temp_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_TEMPERATURE,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Celsius"
+    // to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Celsius"
+    // to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Celsius"
+    // to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(16),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "Celsius"
+    // to provide 2 digits past the decimal point
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Ambient light sensor example.
+ */
+const unsigned char als_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,         // USAGE_PAGE (Sensor)
+    HID_USAGE_SENSOR_TYPE_LIGHT_AMBIENTLIGHT, // USAGE (AmbientLight)
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_LIGHT_ILLUMINANCE,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_REL_PCT),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0x10,0x27), // 10000 = 0.00 to 100.00 percent with 2 digits past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),  // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_LIGHT_ILLUMINANCE,HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_LIGHT_ILLUMINANCE,HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //add this definition if required by the specific application
+    HID_USAGE_SENSOR_PROPERTY_RESPONSE_CURVE,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(10), //as required for n pair of values
+    HID_UNIT_EXPONENT(0x0), // scale default unit to provide 0 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_LIGHT_ILLUMINANCE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_LIGHT_COLOR_TEMPERATURE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_UNIT_EXPONENT(0),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_LIGHT_CHROMATICITY_X,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_UNIT_EXPONENT(0x0C), // scale default unit to provide 4 digits past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_LIGHT_CHROMATICITY_Y,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_UNIT_EXPONENT(0x0C), // scale default unit to provide 4 digits past decimal point
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * 3D accelerometer sensor example.
+ */
+const unsigned char accel3_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_MOTION_ACCELEROMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),  // scale default unit Gs to centi-Gs
+    // to provide 2 digits past Gs decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION,HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),  // scale default unit Gs to centi-Gs
+    // to provide 2 digits past Gs decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION,HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),  // scale default unit Gs to centi-Gs
+    // to provide 2 digits past Gs decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_X_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),  // scale default unit Gs to centi-Gs
+    // to provide 2 digits past Gs decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_Y_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),  // scale default unit Gs to centi-Gs
+    // to provide 2 digits past Gs decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_Z_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),  // scale default unit Gs to centi-Gs
+    // to provide 2 digits past Gs decimal point
+    HID_INPUT(Data_Var_Abs),
+
+    //include the following datafield if required to support the “shake” event
+    HID_USAGE_SENSOR_DATA_MOTION_STATE,
+    HID_LOGICAL_MIN_8(0), // False = Still
+    HID_LOGICAL_MAX_8(1), // True = In Motion
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * 3D gyroscope sensor example.
+ */
+const unsigned char gyro3_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY_X_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY_Y_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY_Z_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * 3D compass sensor example.
+ */
+const unsigned char comp3_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_ORIENTATION_COMPASS_3D,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_HEADING,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_HEADING,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_HEADING,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_COMPENSATED_MAGNETIC_NORTH,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_COMPENSATED_TRUE_NORTH,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_NORTH,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_TRUE_NORTH,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0F), // scale default unit to provide 1 digit past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX_X_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0D), // scale default unit to "milliGauss"
+    // to provide 3 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX_Y_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0D), // scale default unit to "milliGauss"
+    // to provide 3 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX_Z_AXIS,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0D), // scale default unit to "milliGauss"
+    // to provide 3 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_LOW,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_MEDIUM,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_HIGH,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * 3D inclinomater example.
+ */
+const unsigned char inc3_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_ORIENTATION_INCLINOMETER_3D,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_TILT,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_TILT,HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_TILT,HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_TILT_X,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_TILT_Y,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_TILT_Z,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit to provide 2 digits past decimal point
+    HID_INPUT(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_LOW,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_MEDIUM,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_HIGH,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+
+    HID_END_COLLECTION
+};
+
+
+/**
+ * Device orientation sensor example. Note this maps to rotation vector sensor in android.
+ */
+const unsigned char devor_report_descriptor[] = {
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_TYPE_ORIENTATION_DEVICE_ORIENTATION,
+    HID_COLLECTION(Physical),
+
+    //feature reports (xmit/receive)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  // NAry
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL,
+    HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_FEATURE(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
+    HID_REPORT_SIZE(32),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_ABS,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E), // scale default unit "meter" to provide 2 digits past the decimal point
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_QUATERNION,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_QUATERNION,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x01),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_QUATERNION,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x01),
+    HID_FEATURE(Data_Var_Abs),
+
+    //include this if the values are calculated in firmware
+    //otherwise, the driver will calculate these values from the Quaternion
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_ROTATION_MATRIX,
+                          HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS),
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_16(0xFF,0xFF),
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_ROTATION_MATRIX,
+                          HID_USAGE_SENSOR_DATA_MOD_MAX),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),
+    HID_FEATURE(Data_Var_Abs),
+    HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_ROTATION_MATRIX,
+                          HID_USAGE_SENSOR_DATA_MOD_MIN),
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(1),
+    HID_UNIT_EXPONENT(0x0E),
+    HID_FEATURE(Data_Var_Abs),
+
+    //input reports (transmit)
+    HID_USAGE_PAGE_SENSOR,
+    HID_USAGE_SENSOR_STATE,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(6),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_STATE_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_STATE_READY_SEL,
+    HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL,
+    HID_USAGE_SENSOR_STATE_NO_DATA_SEL,
+    HID_USAGE_SENSOR_STATE_INITIALIZING_SEL,
+    HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL,
+    HID_USAGE_SENSOR_STATE_ERROR_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_EVENT,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(5),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL,
+    HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL,
+    HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL,
+    HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL,
+    HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_QUATERNION,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(4),
+    HID_UNIT_EXPONENT(0x0E),
+    HID_INPUT(Data_Arr_Abs),
+
+    //include this if the values are calculated in firmware
+    //otherwise, the driver will calculate these values from the Quaternion
+    HID_USAGE_SENSOR_DATA_ORIENTATION_ROTATION_MATRIX,
+    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
+    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
+    HID_REPORT_SIZE(16),
+    HID_REPORT_COUNT(9),
+    HID_UNIT_EXPONENT(0x0F),
+    HID_INPUT(Data_Arr_Abs),
+
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY,
+    HID_LOGICAL_MIN_8(0),
+    HID_LOGICAL_MAX_8(2),
+    HID_REPORT_SIZE(8),
+    HID_REPORT_COUNT(1),
+    HID_COLLECTION(Logical),
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_LOW,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_MEDIUM,
+    HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_HIGH,
+    HID_INPUT(Data_Arr_Abs),
+    HID_END_COLLECTION,
+
+    HID_END_COLLECTION
+};
+} // annoymous namespace
+
+/**
+ * Global test vector entry.
+ */
+#define TEST_DESCRIPTOR(name) \
+    { name ## _report_descriptor, sizeof(name ## _report_descriptor), #name }
+
+const TestHidDescriptor gDescriptorArray[] = {
+    TEST_DESCRIPTOR(accel3),
+    TEST_DESCRIPTOR(col1),
+    TEST_DESCRIPTOR(col2),
+    TEST_DESCRIPTOR(col3),
+    TEST_DESCRIPTOR(cus1),
+    TEST_DESCRIPTOR(cus2),
+    TEST_DESCRIPTOR(cus3),
+    TEST_DESCRIPTOR(cus4),
+    TEST_DESCRIPTOR(pres),
+    TEST_DESCRIPTOR(prox),
+    TEST_DESCRIPTOR(bar),
+    TEST_DESCRIPTOR(humi),
+    TEST_DESCRIPTOR(temp),
+    TEST_DESCRIPTOR(als),
+    TEST_DESCRIPTOR(gyro3),
+    TEST_DESCRIPTOR(comp3),
+    TEST_DESCRIPTOR(inc3),
+    TEST_DESCRIPTOR(devor),
+    {nullptr, 0, nullptr} //sentinel
+};
+#undef TEST_DESCRIPTOR
+
+const TestHidDescriptor *findTestDescriptor(const char *name) {
+    if (name == nullptr) {
+        return nullptr;
+    }
+
+    for (const TestHidDescriptor *p = gDescriptorArray; ; ++p) {
+        if (p->data == nullptr || p->len == 0) {
+            break;
+        }
+        if (strcmp(p->name, name) == 0) {
+            return p;
+        }
+    }
+    return nullptr;
+}
diff --git a/modules/sensors/dynamic_sensor/HidUtils/test/TestHidDescriptor.h b/modules/sensors/dynamic_sensor/HidUtils/test/TestHidDescriptor.h
new file mode 100644
index 0000000..417cb72
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/test/TestHidDescriptor.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_TEST_HIDDESCRIPTOR_H_
+#define HIDUTIL_TEST_HIDDESCRIPTOR_H_
+
+#include <cstddef>
+
+struct TestHidDescriptor {
+    const unsigned char *data;
+    size_t len;
+    const char *name;
+};
+
+extern const TestHidDescriptor gDescriptorArray[];
+const TestHidDescriptor *findTestDescriptor(const char *name);
+
+#endif // HIDUTIL_TEST_HIDDESCRIPTOR_H_
diff --git a/modules/sensors/dynamic_sensor/HidUtils/test/TestHidSensorSpec.h b/modules/sensors/dynamic_sensor/HidUtils/test/TestHidSensorSpec.h
new file mode 100644
index 0000000..522cb6c
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/test/TestHidSensorSpec.h
@@ -0,0 +1,859 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HIDUTIL_TEST_HIDSENSORSPEC_H
+#define HIDUTIL_TEST_HIDSENSORSPEC_H
+/**
+ * Example HID sensor definition in from published document "HID Sensors Usage"
+ * (hid-sensors-usage.docx). This file is added as part of the test case.
+ *
+ * It is slightly modified in order to compile.
+ */
+#define HID_USAGE_PAGE_SENSOR                                                           0x05,0x20
+
+//sensor category usages
+#define HID_USAGE_SENSOR_TYPE_COLLECTION                                                0x09,0x01
+//sensor category biometric
+#define HID_USAGE_SENSOR_CATEGORY_BIOMETRIC                                             0x09,0x10
+#define HID_USAGE_SENSOR_TYPE_BIOMETRIC_PRESENCE                                        0x09,0x11
+#define HID_USAGE_SENSOR_TYPE_BIOMETRIC_PROXIMITY                                       0x09,0x12
+#define HID_USAGE_SENSOR_TYPE_BIOMETRIC_TOUCH                                           0x09,0x13
+//sensor category electrical
+#define HID_USAGE_SENSOR_CATEGORY_ELECTRICAL                                            0x09,0x20
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_CAPACITANCE                                    0x09,0x21
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_CURRENT                                        0x09,0x22
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_POWER                                          0x09,0x23
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_INDUCTANCE                                     0x09,0x24
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_RESISTANCE                                     0x09,0x25
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_VOLTAGE                                        0x09,0x26
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_POTENTIOMETER                                  0x09,0x27
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_FREQUENCY                                      0x09,0x28
+#define HID_USAGE_SENSOR_TYPE_ELECTRICAL_PERIOD                                         0x09,0x29
+//sensor category environmental
+#define HID_USAGE_SENSOR_CATEGORY_ENVIRONMENTAL                                         0x09,0x30
+#define HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_ATMOSPHERIC_PRESSURE                        0x09,0x31
+#define HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_HUMIDITY                                    0x09,0x32
+#define HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_TEMPERATURE                                 0x09,0x33
+#define HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_WIND_DIRECTION                              0x09,0x34
+#define HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_WIND_SPEED                                  0x09,0x35
+//sensor category light
+#define HID_USAGE_SENSOR_CATEGORY_LIGHT                                                 0x09,0x40
+#define HID_USAGE_SENSOR_TYPE_LIGHT_AMBIENTLIGHT                                        0x09,0x41
+#define HID_USAGE_SENSOR_TYPE_LIGHT_CONSUMER_INFRARED                                   0x09,0x42
+//sensor category location
+#define HID_USAGE_SENSOR_CATEGORY_LOCATION                                              0x09,0x50
+#define HID_USAGE_SENSOR_TYPE_LOCATION_BROADCAST                                        0x09,0x51
+#define HID_USAGE_SENSOR_TYPE_LOCATION_DEAD_RECKONING                                   0x09,0x52
+#define HID_USAGE_SENSOR_TYPE_LOCATION_GPS                                              0x09,0x53
+#define HID_USAGE_SENSOR_TYPE_LOCATION_LOOKUP                                           0x09,0x54
+#define HID_USAGE_SENSOR_TYPE_LOCATION_OTHER                                            0x09,0x55
+#define HID_USAGE_SENSOR_TYPE_LOCATION_STATIC                                           0x09,0x56
+#define HID_USAGE_SENSOR_TYPE_LOCATION_TRIANGULATION                                    0x09,0x57
+//sensor category mechanical
+#define HID_USAGE_SENSOR_CATEGORY_MECHANICAL                                            0x09,0x60
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_BOOLEAN_SWITCH                                 0x09,0x61
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_BOOLEAN_SWITCH_ARRAY                           0x09,0x62
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_MULTIVALUE_SWITCH                              0x09,0x63
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_FORCE                                          0x09,0x64
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_PRESSURE                                       0x09,0x65
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_STRAIN                                         0x09,0x66
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_SCALE_WEIGHT                                   0x09,0x67
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_VIBRATOR                                       0x09,0x68
+#define HID_USAGE_SENSOR_TYPE_MECHANICAL_HALL_EFFECT_SWITCH                             0x09,0x69
+//sensor category motion
+#define HID_USAGE_SENSOR_CATEGORY_MOTION                                                0x09,0x70
+#define HID_USAGE_SENSOR_TYPE_MOTION_ACCELEROMETER_1D                                   0x09,0x71
+#define HID_USAGE_SENSOR_TYPE_MOTION_ACCELEROMETER_2D                                   0x09,0x72
+#define HID_USAGE_SENSOR_TYPE_MOTION_ACCELEROMETER_3D                                   0x09,0x73
+#define HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER_1D                                       0x09,0x74
+#define HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER_2D                                       0x09,0x75
+#define HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER_3D                                       0x09,0x76
+#define HID_USAGE_SENSOR_TYPE_MOTION_MOTION_DETECTOR                                    0x09,0x77
+#define HID_USAGE_SENSOR_TYPE_MOTION_SPEEDOMETER                                        0x09,0x78
+#define HID_USAGE_SENSOR_TYPE_MOTION_ACCELEROMETER                                      0x09,0x79
+#define HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER                                          0x09,0x7A
+//sensor category orientation
+#define HID_USAGE_SENSOR_CATEGORY_ORIENTATION                                           0x09,0x80
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_COMPASS_1D                                    0x09,0x81
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_COMPASS_2D                                    0x09,0x82
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_COMPASS_3D                                    0x09,0x83
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_INCLINOMETER_1D                               0x09,0x84
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_INCLINOMETER_2D                               0x09,0x85
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_INCLINOMETER_3D                               0x09,0x86
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_DISTANCE_1D                                   0x09,0x87
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_DISTANCE_2D                                   0x09,0x88
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_DISTANCE_3D                                   0x09,0x89
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_DEVICE_ORIENTATION                            0x09,0x8A
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_COMPASS                                       0x09,0x8B
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_INCLINOMETER                                  0x09,0x8C
+#define HID_USAGE_SENSOR_TYPE_ORIENTATION_DISTANCE                                      0x09,0x8D
+//sensor category scanner
+#define HID_USAGE_SENSOR_CATEGORY_SCANNER                                               0x09,0x90
+#define HID_USAGE_SENSOR_TYPE_SCANNER_BARCODE                                           0x09,0x91
+#define HID_USAGE_SENSOR_TYPE_SCANNER_RFID                                              0x09,0x92
+#define HID_USAGE_SENSOR_TYPE_SCANNER_NFC                                               0x09,0x93
+//sensor category time
+#define HID_USAGE_SENSOR_CATEGORY_TIME                                                  0x09,0xA0
+#define HID_USAGE_SENSOR_TYPE_TIME_ALARM                                                0x09,0xA1
+#define HID_USAGE_SENSOR_TYPE_TIME_RTC                                                  0x09,0xA2
+//sensor category other
+#define HID_USAGE_SENSOR_CATEGORY_OTHER                                                 0x09,0xE0
+#define HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM                                              0x09,0xE1
+#define HID_USAGE_SENSOR_TYPE_OTHER_GENERIC                                             0x09,0xE2
+#define HID_USAGE_SENSOR_TYPE_OTHER_GENERIC_ENUMERATOR                                  0x09,0xE3
+
+//unit usages
+#define HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED                                            0x65,0x00                // Unit
+#define HID_USAGE_SENSOR_UNITS_LUX                                                      0x67,0xE1,0x00,0x00,0x01 // Unit
+#define HID_USAGE_SENSOR_UNITS_KELVIN                                                   0x67,0x01,0x00,0x01,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_FAHRENHEIT                                               0x67,0x03,0x00,0x01,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_PASCAL                                                   0x66,0xF1,0xE1           // Unit
+#define HID_USAGE_SENSOR_UNITS_NEWTON                                                   0x66,0x11,0xE1           // Unit
+#define HID_USAGE_SENSOR_UNITS_METERS_PER_SECOND                                        0x66,0x11,0xF0           // Unit
+#define HID_USAGE_SENSOR_UNITS_METERS_PER_SEC_SQRD                                      0x66,0x11,0xE0           // Unit
+#define HID_USAGE_SENSOR_UNITS_FARAD                                                    0x67,0xE1,0x4F,0x20,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_AMPERE                                                   0x67,0x01,0x00,0x10,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_WATT                                                     0x66,0x21,0xD1           // Unit
+#define HID_USAGE_SENSOR_UNITS_HENRY                                                    0x67,0x21,0xE1,0xE0,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_OHM                                                      0x67,0x21,0xD1,0xE0,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_VOLT                                                     0x67,0x21,0xD1,0xF0,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_HERTZ                                                    0x66,0x01,0xF0           // Unit
+#define HID_USAGE_SENSOR_UNITS_DEGREES                                                  0x65,0x14                // Unit
+#define HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND                                       0x66,0x14,0xF0           // Unit
+#define HID_USAGE_SENSOR_UNITS_DEGREES_PER_SEC_SQRD                                     0x66,0x14,0xE0           // Unit
+#define HID_USAGE_SENSOR_UNITS_RADIANS                                                  0x65,0x12                // Unit
+#define HID_USAGE_SENSOR_UNITS_RADIANS_PER_SECOND                                       0x66,0x12,0xF0           // Unit
+#define HID_USAGE_SENSOR_UNITS_RADIANS_PER_SEC_SQRD                                     0x66,0x12,0xE0           // Unit
+#define HID_USAGE_SENSOR_UNITS_SECOND                                                   0x66,0x01,0x10           // Unit
+#define HID_USAGE_SENSOR_UNITS_GAUSS                                                    0x67,0x01,0xE1,0xF0,0x00 // Unit
+#define HID_USAGE_SENSOR_UNITS_GRAM                                                     0x66,0x01,0x01           // Unit
+#define HID_USAGE_SENSOR_UNITS_CENTIMETER                                               0x65,0x11                // Unit
+#ifdef DEFINE_NON_HID_UNITS
+#define HID_USAGE_SENSOR_UNITS_CELSIUS              "Use Unit(Kelvin) and subtract 273.15"
+#define HID_USAGE_SENSOR_UNITS_KILOGRAM             "Use Unit(gram) and UnitExponent(0x03)"
+#define HID_USAGE_SENSOR_UNITS_METER                "Use Unit(centimeter) and UnitExponent(0x02)"
+#define HID_USAGE_SENSOR_UNITS_BAR                  "Use Unit(Pascal) and UnitExponent(0x05)"
+#define HID_USAGE_SENSOR_UNITS_KNOT                 "Use Unit(m/s) and multiply by 1852/3600"
+#define HID_USAGE_SENSOR_UNITS_PERCENT              "Use Unit(Not_Specified)"
+#define HID_USAGE_SENSOR_UNITS_G                    "Use Unit(m/s2) and divide by 9.8"
+#define HID_USAGE_SENSOR_UNITS_MILLISECOND          "Use Unit(second) and UnitExponent(0x0D)"
+#define HID_USAGE_SENSOR_UNITS_MILLIGAUSS           "Use Unit(Gauss) and UnitExponent(0x0D)"
+#endif
+//unit deprecated usages
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_LUX                                           0x01
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_KELVIN                                        0x02
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_CELSIUS                                       0x03
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_PASCAL                                        0x04
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_NEWTON                                        0x05
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_METERS_PER_SECOND                             0x06
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_KILOGRAM                                      0x07
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_METER                                         0x08
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_METERS_PER_SEC_SQRD                           0x09
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_FARAD                                         0x0A
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_AMPERE                                        0x0B
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_WATT                                          0x0C
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_HENRY                                         0x0D
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_OHM                                           0x0E
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_VOLT                                          0x0F
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_HERTZ                                         0x10
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_BAR                                           0x11
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_DEGREES_ANTI_CLOCKWISE                        0x12
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_DEGREES_CLOCKWISE                             0x13
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_DEGREE                                        0x14
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_DEGREES_PER_SECOND                            0x15
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_KNOT                                          0x16
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_PERCENT                                       0x17
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_SECOND                                        0x18
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_MILLISECOND                                   0x19
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_G                                             0x1A
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_BYTES                                         0x1B
+#define HID_USAGE_SENSOR_UNITS_DEPRECATED_MILLIGAUSS                                    0x1C
+
+//data type usage modifiers -- we use them as modifiers for sensor properties & data fields
+//to create thresholds, for example.
+//NOTE: the usage tables actually define these as two bytes, but in order
+//to get the define macros to work so these are ‘or-ed’ these are defined
+//here as only one byte.
+#define HID_USAGE_SENSOR_DATA_MOD_NONE                                                  0x00 // US
+#define HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS                                0x10 // US
+#define HID_USAGE_SENSOR_DATA_MOD_MAX                                                   0x20 // US
+#define HID_USAGE_SENSOR_DATA_MOD_MIN                                                   0x30 // US
+#define HID_USAGE_SENSOR_DATA_MOD_ACCURACY                                              0x40 // US
+#define HID_USAGE_SENSOR_DATA_MOD_RESOLUTION                                            0x50 // US
+#define HID_USAGE_SENSOR_DATA_MOD_THRESHOLD_HIGH                                        0x60 // US
+#define HID_USAGE_SENSOR_DATA_MOD_THRESHOLD_LOW                                         0x70 // US
+#define HID_USAGE_SENSOR_DATA_MOD_CALIBRATION_OFFSET                                    0x80 // US
+#define HID_USAGE_SENSOR_DATA_MOD_CALIBRATION_MULTIPLIER                                0x90 // US
+#define HID_USAGE_SENSOR_DATA_MOD_REPORT_INTERVAL                                       0xA0 // US
+#define HID_USAGE_SENSOR_DATA_MOD_FREQUENCY_MAX                                         0xB0 // US
+#define HID_USAGE_SENSOR_DATA_MOD_PERIOD_MAX                                            0xC0 // US
+#define HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_RANGE_PCT                          0xD0 // US
+#define HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_REL_PCT                            0xE0 // US
+#define HID_USAGE_SENSOR_DATA_MOD_VENDOR_RESERVED                                       0xF0 // US
+
+
+//state usages
+#define HID_USAGE_SENSOR_STATE                                                          0x0A,0x01,0x02 // NAry
+//state selectors
+#define HID_USAGE_SENSOR_STATE_UNKNOWN_SEL                                              0x0A,0x00,0x08 // Sel
+#define HID_USAGE_SENSOR_STATE_READY_SEL                                                0x0A,0x01,0x08 // Sel
+#define HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL                                        0x0A,0x02,0x08 // Sel
+#define HID_USAGE_SENSOR_STATE_NO_DATA_SEL                                              0x0A,0x03,0x08 // Sel
+#define HID_USAGE_SENSOR_STATE_INITIALIZING_SEL                                         0x0A,0x04,0x08 // Sel
+#define HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL                                        0x0A,0x05,0x08 // Sel
+#define HID_USAGE_SENSOR_STATE_ERROR_SEL                                                0x0A,0x06,0x08 // Sel
+//state enums
+#define HID_USAGE_SENSOR_STATE_UNKNOWN_ENUM                                             0x01 // Enum
+#define HID_USAGE_SENSOR_STATE_READY_ENUM                                               0x02 // Enum
+#define HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_ENUM                                       0x03 // Enum
+#define HID_USAGE_SENSOR_STATE_NO_DATA_ENUM                                             0x04 // Enum
+#define HID_USAGE_SENSOR_STATE_INITIALIZING_ENUM                                        0x05 // Enum
+#define HID_USAGE_SENSOR_STATE_ACCESS_DENIED_ENUM                                       0x06 // Enum
+#define HID_USAGE_SENSOR_STATE_ERROR_ENUM                                               0x07 // Enum
+//state deprecated enums
+#define HID_USAGE_SENSOR_STATE_DEPRECATED_UNKNOWN_ENUM                                  0x00
+#define HID_USAGE_SENSOR_STATE_DEPRECATED_NOT_AVAILABLE_ENUM                            0x01
+#define HID_USAGE_SENSOR_STATE_DEPRECATED_READY_ENUM                                    0x02
+#define HID_USAGE_SENSOR_STATE_DEPRECATED_NO_DATA_ENUM                                  0x03
+#define HID_USAGE_SENSOR_STATE_DEPRECATED_INITIALIZING_ENUM                             0x04
+#define HID_USAGE_SENSOR_STATE_DEPRECATED_ACCESS_DENIED_ENUM                            0x05
+#define HID_USAGE_SENSOR_STATE_DEPRECATED_ERROR_ENUM                                    0x06
+
+//event usages
+#define HID_USAGE_SENSOR_EVENT                                                          0x0A,0x02,0x02 // NAry
+//event selectors
+#define HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL                                              0x0A,0x10,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL                                        0x0A,0x11,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL                                     0x0A,0x12,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL                                         0x0A,0x13,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL                                        0x0A,0x14,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL                                   0x0A,0x15,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_MAX_REACHED_SEL                                          0x0A,0x16,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_MIN_REACHED_SEL                                          0x0A,0x17,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_UPWARD_SEL                          0x0A,0x18,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_HIGH_THESHOLD_CROSS_ABOVE_SEL        HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_UPWARD_SEL
+#define HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_DOWNWARD_SEL                        0x0A,0x19,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_BELOW_SEL       HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_DOWNWARD_SEL
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_UPWARD_SEL                           0x0A,0x1A,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_ABOVE_SEL        HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_UPWARD_SEL
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_DOWNWARD_SEL                         0x0A,0x1B,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_BELOW_SEL        HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_DOWNWARD_SEL
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_UPWARD_SEL                          0x0A,0x1C,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_ABOVE_SEL       HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_UPWARD_SEL
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_DOWNWARD_SEL                        0x0A,0x1D,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_BELOW_SEL       HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_DOWNWARD_SEL
+#define HID_USAGE_SENSOR_EVENT_PERIOD_EXCEEDED_SEL                                      0x0A,0x1E,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_FREQUENCY_EXCEEDED_SEL                                   0x0A,0x1F,0x08 // Sel
+#define HID_USAGE_SENSOR_EVENT_COMPLEX_TRIGGER_SEL                                      0x0A,0x20,0x08 // Sel
+//event enums
+#define HID_USAGE_SENSOR_EVENT_UNKNOWN_ENUM                                             0x01 // Enum
+#define HID_USAGE_SENSOR_EVENT_STATE_CHANGED_ENUM                                       0x02 // Enum
+#define HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_ENUM                                    0x03 // Enum
+#define HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM                                        0x04 // Enum
+#define HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_ENUM                                       0x05 // Enum
+#define HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_ENUM                                  0x06 // Enum
+#define HID_USAGE_SENSOR_EVENT_MAX_REACHED_ENUM                                         0x07 // Enum
+#define HID_USAGE_SENSOR_EVENT_MIN_REACHED_ENUM                                         0x08 // Enum
+#define HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_UPWARD_ENUM                         0x09 // Enum
+#define HID_USAGE_SENSOR_EVENT_HIGH_THESHOLD_CROSS_ABOVE_ENUM   HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_UPWARD_ENUM
+#define HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_DOWNWARD_ENUM                       0x0A // Enum
+#define HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_BELOW_ENUM  HID_USAGE_SENSOR_EVENT_HIGH_THRESHOLD_CROSS_DOWNWARD_ENUM
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_UPWARD_ENUM                          0x0B // Enum
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_ABOVE_ENUM   HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_UPWARD_ENUM
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_DOWNWARD_ENUM                        0x0C // Enum
+#define HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_BELOW_ENUM   HID_USAGE_SENSOR_EVENT_LOW_THRESHOLD_CROSS_DOWNWARD_ENUM
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_UPWARD_ENUM                         0x0D // Enum
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_ABOVE_ENUM  HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_UPWARD_ENUM
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_DOWNWARD_ENUM                       0x0E // Enum
+#define HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_BELOW_ENUM  HID_USAGE_SENSOR_EVENT_ZERO_THRESHOLD_CROSS_DOWNWARD_ENUM
+#define HID_USAGE_SENSOR_EVENT_PERIOD_EXCEEDED_ENUM                                     0x0F // Enum
+#define HID_USAGE_SENSOR_EVENT_FREQUENCY_EXCEEDED_ENUM                                  0x10 // Enum
+#define HID_USAGE_SENSOR_EVENT_COMPLEX_TRIGGER_ENUM                                     0x11 // Enum
+//event deprecated enums
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_UNKNOWN_ENUM                                  0x00
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_STATE_CHANGED_ENUM                            0x01
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_PROPERTY_CHANGED_ENUM                         0x02
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_DATA_UPDATE_ENUM                              0x03
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_POLL_RESPONSE_ENUM                            0x04
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_CHANGE_SENSITIVITY_ENUM                       0x05
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_MAX_REACHED_ENUM                              0x06
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_MIN_REACHED_ENUM                              0x07
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_HIGH_THRESHHOLD_CROSS_ABOVE_ENUM              0x08
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_HIGH_THRESHHOLD_CROSS_BELOW_ENUM              0x09
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_LOW_THRESHHOLD_CROSS_ABOVE_ENUM               0x0A
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_LOW_THRESHHOLD_CROSS_BELOW_ENUM               0x0B
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_ZERO_THRESHOLD_CROSS_ABOVE_ENUM               0x0C
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_ZERO_THRESHOLD_CROSS_BELOW_ENUM               0x0D
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_PERIOD_EXCEEDED_ENUM                          0x0E
+#define HID_USAGE_SENSOR_EVENT_DEPRECATED_FREQUENCY_EXCEEDED_ENUM                       0x0F
+
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY                                                       0x0A,0x00,0x03
+#define HID_USAGE_SENSOR_PROPERTY_FRIENDLY_NAME                                         0x0A,0x01,0x03
+#define HID_USAGE_SENSOR_PROPERTY_PERSISTENT_UNIQUE_ID                                  0x0A,0x02,0x03
+#define HID_USAGE_SENSOR_PROPERTY_SENSOR_STATUS                                         0x0A,0x03,0x03
+#define HID_USAGE_SENSOR_PROPERTY_MINIMUM_REPORT_INTERVAL                               0x0A,0x04,0x03
+#define HID_USAGE_SENSOR_PROPERTY_SENSOR_MANUFACTURER                                   0x0A,0x05,0x03
+#define HID_USAGE_SENSOR_PROPERTY_SENSOR_MODEL                                          0x0A,0x06,0x03
+#define HID_USAGE_SENSOR_PROPERTY_SENSOR_SERIAL_NUMBER                                  0x0A,0x07,0x03
+#define HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION                                    0x0A,0x08,0x03
+#define HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE                                0x0A,0x09,0x03 // NAry
+//begin connection type selectors
+#define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL                     0x0A,0x30,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL                       0x0A,0x31,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL                       0x0A,0x32,0x08 // Sel
+//end connection type selectors
+//begin connection type enums
+#define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_ENUM                    0x01 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_ENUM                      0x02 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_ENUM                      0x03 // Enum
+//end connection type enums
+//begin connection type deprecated enums
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_CONNECTION_TYPE_PC_INTEGRATED_ENUM         0x00 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_CONNECTION_TYPE_PC_ATTACHED_ENUM           0x01 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_CONNECTION_TYPE_PC_EXTERNAL_ENUM           0x02 // Enum
+//end connection type deprecated enums
+#define HID_USAGE_SENSOR_PROPERTY_SENSOR_DEVICE_PATH                                    0x0A,0x0A,0x03
+#define HID_USAGE_SENSOR_PROPERTY_HARDWARE_REVISION                                     0x0A,0x0B,0x03
+#define HID_USAGE_SENSOR_PROPERTY_FIRMWARE_VERSION                                      0x0A,0x0C,0x03
+#define HID_USAGE_SENSOR_PROPERTY_RELEASE_DATE                                          0x0A,0x0D,0x03
+#define HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL                                       0x0A,0x0E,0x03
+#define HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_ABS                                0x0A,0x0F,0x03
+#define HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_RANGE_PCT                          0x0A,0x10,0x03
+#define HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_REL_PCT                            0x0A,0x11,0x03
+#define HID_USAGE_SENSOR_PROPERTY_ACCURACY                                              0x0A,0x12,0x03
+#define HID_USAGE_SENSOR_PROPERTY_RESOLUTION                                            0x0A,0x13,0x03
+#define HID_USAGE_SENSOR_PROPERTY_RANGE_MAXIMUM                                         0x0A,0x14,0x03
+#define HID_USAGE_SENSOR_PROPERTY_RANGE_MINIMUM                                         0x0A,0x15,0x03
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE                                       0x0A,0x16,0x03 // NAry
+//begin reporting state selectors
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL                         0x0A,0x40,0x08 // Sel
+#define HID_USAGE_REPORTING_STATE_ON_NONE_SEL       HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL                        0x0A,0x41,0x08 // Sel
+#define HID_USAGE_REPORTING_STATE_ON_ALL_SEL        HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL                  0x0A,0x42,0x08 // Sel
+#define HID_USAGE_REPORTING_STATE_ON_THRESHOLD_SEL  HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_WAKE_SEL                    0x0A,0x43,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_WAKE_SEL                   0x0A,0x44,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL             0x0A,0x45,0x08 // Sel
+//end reporting state selectors
+//begin reporting state enums
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_ENUM                        0x01 // Enum
+#define HID_USAGE_REPORTING_STATE_ON_NONE_ENUM      HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_ENUM
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_ENUM                       0x02 // Enum
+#define HID_USAGE_REPORTING_STATE_ON_ALL_ENUM       HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_ENUM
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_ENUM                 0x03 // Enum
+#define HID_USAGE_REPORTING_STATE_ON_THRESHOLD_ENUM HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_ENUM
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL_WAKE_ENUM                   0x04 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL_WAKE_ENUM                  0x05 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_ENUM            0x06 // Enum
+//end reporting state enums
+//begin reporting state deprecated enums
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_NO_EVENTS_ENUM             0x00 // Enum
+#define HID_USAGE_DEPRECATED_REPORTING_STATE_ON_NONE_ENUM      HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_NO_EVENTS_ENUM
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_ALL_EVENTS_ENUM            0x01 // Enum
+#define HID_USAGE_DEPRECATED_REPORTING_STATE_ON_ALL_ENUM       HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_ALL_EVENTS_ENUM
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_THRESHOLD_EVENTS_ENUM      0x02 // Enum
+#define HID_USAGE_DEPRECATED_REPORTING_STATE_ON_THRESHOLD_ENUM HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_THRESHOLD_EVENTS_ENUM
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_NO_EVENTS_WAKE_ENUM        0x03 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_ALL_EVENTS_WAKE_ENUM       0x04 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_ENUM 0x05 // Enum
+//end reporting state deprecated enums
+#define HID_USAGE_SENSOR_PROPERTY_SAMPLING_RATE                                         0x0A,0x17,0x03
+#define HID_USAGE_SENSOR_PROPERTY_RESPONSE_CURVE                                        0x0A,0x18,0x03
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE                                           0x0A,0x19,0x03 // NAry
+//begin power state selectors
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL                             0x0A,0x50,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL                         0x0A,0x51,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL                          0x0A,0x52,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL                  0x0A,0x53,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL                    0x0A,0x54,0x08 // Sel
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL                          0x0A,0x55,0x08 // Sel
+//end power state selectors
+//begin power state enums
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_ENUM                            0x01 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_ENUM                        0x02 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_ENUM                         0x03 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_ENUM                 0x04 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_ENUM                   0x05 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_ENUM                         0x06 // Enum
+//end power state enums
+//begin deprecated power state enums
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_POWER_STATE_UNDEFINED_ENUM                 0x00 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_POWER_STATE_D0_FULL_POWER_ENUM             0x01 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_POWER_STATE_D1_LOW_POWER_ENUM              0x02 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_POWER_STATE_D2_STANDBY_WITH_WAKE_ENUM      0x03 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_POWER_STATE_D3_SLEEP_WITH_WAKE_ENUM        0x04 // Enum
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_POWER_STATE_D4_POWER_OFF_ENUM              0x05 // Enum
+//end deprecated power state enums
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_FEATURE_PAGE_COUNT                         0x0A,0x1A,0x03
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_FEATURE_PAGE_ID                            0x0A,0x1B,0x03
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_INPUT_PAGE_COUNT                           0x0A,0x1C,0x03
+#define HID_USAGE_SENSOR_PROPERTY_DEPRECATED_INPUT_PAGE_ID                              0x0A,0x1D,0x03
+
+//data type location
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_LOCATION                                                  0x0A,0x00,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_DESIRED_ACCURACY                                 0x0A,0x01,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ALTITUDE_ANTENNA_SEALEVEL                        0x0A,0x02,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_DIFFERENTIAL_REFERENCE_STATION_ID                0x0A,0x03,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ALTITIDE_ELIPSOID_ERROR                          0x0A,0x04,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ALTITIDE_ELIPSOID                                0x0A,0x05,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ALTITUDE_SEALEVEL_ERROR                          0x0A,0x06,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ALTITUDE_SEALEVEL                                0x0A,0x07,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_DGPS_DATA_AGE                                    0x0A,0x08,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ERROR_RADIUS                                     0x0A,0x09,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_FIX_QUALITY                                      0x0A,0x0A,0x04 // NAry
+//begin fix quality selectors
+#define HID_USAGE_SENSOR_DATA_FIX_QUALITY_NO_FIX                                        0x0A,0x70,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_QUALITY_GPS                                           0x0A,0x71,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_QUALITY_DGPS                                          0x0A,0x72,0x08 // Sel
+//end fix quality selectors
+#define HID_USAGE_SENSOR_DATA_LOCATION_FIX_TYPE                                         0x0A,0x0B,0x04 // NAry
+//begin fix type selectors
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_NO_FIX                                           0x0A,0x80,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_GPS_SPS_MODE_FIX_VALID                           0x0A,0x81,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_DGPS_SPS_MODE_FIX_VALID                          0x0A,0x82,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_GPS_PPS_MODE_FIX_VALID                           0x0A,0x83,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_REAL_TIME_KINEMATIC                              0x0A,0x84,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_FLOAT_RTK                                        0x0A,0x85,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_ESTIMATED_DEAD_RECKONING                         0x0A,0x86,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_MANUAL_INPUT_MODE                                0x0A,0x87,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_FIX_TYPE_SIMULATOR_MODE                                   0x0A,0x88,0x08 // Sel
+//end fix type selectors
+#define HID_USAGE_SENSOR_DATA_LOCATION_GEOIDAL_SEPARATION                               0x0A,0x0C,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_GPS_OPERATION_MODE                               0x0A,0x0D,0x04 // NAry
+//begin gps operation mode selectors
+#define HID_USAGE_SENSOR_DATA_GPS_OP_MODE_MANUAL                                        0x0A,0x90,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_GPS_OP_MODE_AUTOMATIC                                     0x0A,0x91,0x08 // Sel
+//end gps operation mode selectors
+#define HID_USAGE_SENSOR_DATA_LOCATION_GPS_SELECTION_MODE                               0x0A,0x0E,0x04 // NAry
+//begin gps selection mode selectors
+#define HID_USAGE_SENSOR_DATA_GPS_SEL_MODE_AUTONOMOUS                                   0x0A,0xA0,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_GPS_SEL_MODE_DGPS                                         0x0A,0xA1,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_GPS_SEL_MODE_ESTIMATED_DEAD_RECKONING                     0x0A,0xA2,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_GPS_SEL_MODE_MANUAL_INPUT                                 0x0A,0xA3,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_GPS_SEL_MODE_SIMULATOR                                    0x0A,0xA4,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_GPS_SEL_MODE_DATA_NOT_VALID                               0x0A,0xA5,0x08 // Sel
+//end gps selection mode selectors
+#define HID_USAGE_SENSOR_DATA_LOCATION_GPS_STATUS                                       0x0A,0x0F,0x04 // NAry
+//begin gps status selectors
+#define HID_USAGE_SENSOR_DATA_GPS_STATUS_DATA_VALID                                     0x0A,0xB0,0x08 // Sel
+#define HID_USAGE_SENSOR_DATA_GPS_STATUS_DATA_NOT_VALID                                 0x0A,0xB1,0x08 // Sel
+//end gps status selectors
+#define HID_USAGE_SENSOR_DATA_LOCATION_POSITION_DILUTION_OF_PRECISION                   0x0A,0x10,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_HORIZONTAL_DILUTION_OF_PRECISION                 0x0A,0x11,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_VERTICAL_DILUTION_OF_PRECISION                   0x0A,0x12,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_LATITUDE                                         0x0A,0x13,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_LONGITUDE                                        0x0A,0x14,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_TRUE_HEADING                                     0x0A,0x15,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_MAGNETIC_HEADING                                 0x0A,0x16,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_MAGNETIC_VARIATION                               0x0A,0x17,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SPEED                                            0x0A,0x18,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_IN_VIEW                               0x0A,0x19,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_IN_VIEW_AZIMUTH                       0x0A,0x1A,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_IN_VIEW_ELEVATION                     0x0A,0x1B,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_IN_VIEW_ID                            0x0A,0x1C,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_IN_VIEW_PRNs                          0x0A,0x1D,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_IN_VIEW_STN_RATIO                     0x0A,0x1E,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_USED_COUNT                            0x0A,0x1F,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_SATELLITES_USED_PRNs                             0x0A,0x20,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_NMEA_SENTENCE                                    0x0A,0x21,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ADDRESS_LINE_1                                   0x0A,0x22,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_ADDRESS_LINE_2                                   0x0A,0x23,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_CITY                                             0x0A,0x24,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_STATE_OR_PROVINCE                                0x0A,0x25,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_COUNTRY_OR_REGION                                0x0A,0x26,0x04
+#define HID_USAGE_SENSOR_DATA_LOCATION_POSTAL_CODE                                      0x0A,0x27,0x04
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY_LOCATION                                              0x0A,0x2A,0x04
+#define HID_USAGE_SENSOR_PROPERTY_LOCATION_DESIRED_ACCURACY                             0x0A,0x2B,0x04 // NAry
+//begin location desired accuracy selectors
+#define HID_USAGE_SENSOR_DESIRED_ACCURACY_DEFAULT                                       0x0A,0x60,0x08 // Sel
+#define HID_USAGE_SENSOR_DESIRED_ACCURACY_HIGH                                          0x0A,0x61,0x08 // Sel
+#define HID_USAGE_SENSOR_DESIRED_ACCURACY_MEDIUM                                        0x0A,0x62,0x08 // Sel
+#define HID_USAGE_SENSOR_DESIRED_ACCURACY_LOW                                           0x0A,0x63,0x08 // Sel
+//end location desired accuracy selectors
+
+//data type environmental
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_ENVIRONMENTAL                                             0x0A,0x30,0x04
+#define HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_ATMOSPHERIC_PRESSURE                        0x0A,0x31,0x04
+#define HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_REFERENCE_PRESSURE                          0x0A,0x32,0x04
+#define HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_RELATIVE_HUMIDITY                           0x0A,0x33,0x04
+#define HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE                                 0x0A,0x34,0x04
+#define HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_WIND_DIRECTION                              0x0A,0x35,0x04
+#define HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_WIND_SPEED                                  0x0A,0x36,0x04
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY_ENVIRONMENTAL                                         0x0A,0x40,0x04
+#define HID_USAGE_SENSOR_PROPERTY_ENVIRONMENTAL_REFERENCE_PRESSURE                      0x0A,0x41,0x04
+
+//data type motion
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_MOTION                                                    0x0A,0x50,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_STATE                                              0x0A,0x51,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION                                       0x0A,0x52,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_X_AXIS                                0x0A,0x53,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_Y_AXIS                                0x0A,0x54,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_Z_AXIS                                0x0A,0x55,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY                                   0x0A,0x56,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY_X_AXIS                            0x0A,0x57,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY_Y_AXIS                            0x0A,0x58,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY_Z_AXIS                            0x0A,0x59,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_POSITION                                   0x0A,0x5A,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_POSITION_X_AXIS                            0x0A,0x5B,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_POSITION_Y_AXIS                            0x0A,0x5C,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_POSITION_Z_AXIS                            0x0A,0x5D,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_SPEED                                              0x0A,0x5E,0x04
+#define HID_USAGE_SENSOR_DATA_MOTION_INTENSITY                                          0x0A,0x5F,0x04
+
+//data type orientation
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_ORIENTATION                                               0x0A,0x70,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_HEADING                              0x0A,0x71,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_HEADING_X                            0x0A,0x72,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_HEADING_Y                            0x0A,0x73,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_HEADING_Z                            0x0A,0x74,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_COMPENSATED_MAGNETIC_NORTH                    0x0A,0x75,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_COMPENSATED_TRUE_NORTH                        0x0A,0x76,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_NORTH                                0x0A,0x77,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_TRUE_NORTH                                    0x0A,0x78,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_DISTANCE                                      0x0A,0x79,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_DISTANCE_X                                    0x0A,0x7A,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_DISTANCE_Y                                    0x0A,0x7B,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_DISTANCE_Z                                    0x0A,0x7C,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_DISTANCE_OUT_OF_RANGE                         0x0A,0x7D,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_TILT                                          0x0A,0x7E,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_TILT_X                                        0x0A,0x7F,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_TILT_Y                                        0x0A,0x80,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_TILT_Z                                        0x0A,0x81,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_ROTATION_MATRIX                               0x0A,0x82,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_QUATERNION                                    0x0A,0x83,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX                                 0x0A,0x84,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX_X_AXIS                          0x0A,0x85,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX_Y_AXIS                          0x0A,0x86,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETIC_FLUX_Z_AXIS                          0x0A,0x87,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY                             0x0A,0x88,0x04
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_LOW                         0x0A,0xE0,0x08
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_MEDIUM                      0x0A,0xE1,0x08
+#define HID_USAGE_SENSOR_DATA_ORIENTATION_MAGNETOMETER_ACCURACY_HIGH                        0x0A,0xE2,0x08
+
+//data type mechanical
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_MECHANICAL                                                0x0A,0x90,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_BOOLEAN_SWITCH_STATE                           0x0A,0x91,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_BOOLEAN_SWITCH_ARRAY_STATES                    0x0A,0x92,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_MULTIVALUE_SWITCH_VALUE                        0x0A,0x93,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_FORCE                                          0x0A,0x94,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_ABSOLUTE_PRESSURE                              0x0A,0x95,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_GAUGE_PRESSURE                                 0x0A,0x96,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_STRAIN                                         0x0A,0x97,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_WEIGHT                                         0x0A,0x98,0x04
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY_MECHANICAL                                            0x0A,0xA0,0x04
+#define HID_USAGE_SENSOR_PROPERTY_MECHANICAL_VIBRATION_STATE                            0x0A,0xA1,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_VIBRATION_SPEED_FORWARD                        0x0A,0xA2,0x04
+#define HID_USAGE_SENSOR_DATA_MECHANICAL_VIBRATION_SPEED_BACKWARD                       0x0A,0xA3,0x04
+
+//data type biometric
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_BIOMETRIC                                                 0x0A,0xB0,0x04
+#define HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PRESENCE                                  0x0A,0xB1,0x04
+#define HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PROXIMITY_RANGE                           0x0A,0xB2,0x04
+#define HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_PROXIMITY_OUT_OF_RANGE                    0x0A,0xB3,0x04
+#define HID_USAGE_SENSOR_DATA_BIOMETRIC_HUMAN_TOUCH_STATE                               0x0A,0xB4,0x04
+
+//data type light sensor
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_LIGHT                                                     0x0A,0xD0,0x04
+#define HID_USAGE_SENSOR_DATA_LIGHT_ILLUMINANCE                                         0x0A,0xD1,0x04
+#define HID_USAGE_SENSOR_DATA_LIGHT_COLOR_TEMPERATURE                                   0x0A,0xD2,0x04
+#define HID_USAGE_SENSOR_DATA_LIGHT_CHROMATICITY                                        0x0A,0xD3,0x04
+#define HID_USAGE_SENSOR_DATA_LIGHT_CHROMATICITY_X                                      0x0A,0xD4,0x04
+#define HID_USAGE_SENSOR_DATA_LIGHT_CHROMATICITY_Y                                      0x0A,0xD5,0x04
+#define HID_USAGE_SENSOR_DATA_LIGHT_CONSUMER_IR_SENTENCE_RECEIVE                        0x0A,0xD6,0x04
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY_LIGHT                                                 0x0A,0xE0,0x04
+#define HID_USAGE_SENSOR_PROPERTY_LIGHT_CONSUMER_IR_SENTENCE_SEND                       0x0A,0xE1,0x04
+
+//data type scanner
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_SCANNER                                                   0x0A,0xF0,0x04
+#define HID_USAGE_SENSOR_DATA_SCANNER_RFID_TAG                                          0x0A,0xF1,0x04
+#define HID_USAGE_SENSOR_DATA_SCANNER_NFC_SENTENCE_RECEIVE                              0x0A,0xF2,0x04
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY_SCANNER                                               0x0A,0xF8,0x04
+#define HID_USAGE_SENSOR_PROPERTY_SCANNER_NFC_SENTENCE_SEND                             0x0A,0xF9,0x04
+
+//data type electrical
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL                                                0x0A,0x00,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_CAPACITANCE                                    0x0A,0x01,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_CURRENT                                        0x0A,0x02,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_POWER                                          0x0A,0x03,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_INDUCTANCE                                     0x0A,0x04,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_RESISTANCE                                     0x0A,0x05,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_VOLTAGE                                        0x0A,0x06,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_FREQUENCY                                      0x0A,0x07,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_PERIOD                                         0x0A,0x08,0x05
+#define HID_USAGE_SENSOR_DATA_ELECTRICAL_PERCENT_OF_RANGE                               0x0A,0x09,0x05
+
+//data type time
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_TIME                                                      0x0A,0x20,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_YEAR                                                 0x0A,0x21,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_MONTH                                                0x0A,0x22,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_DAY                                                  0x0A,0x23,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_DAY_OF_WEEK                                          0x0A,0x24,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_HOUR                                                 0x0A,0x25,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_MINUTE                                               0x0A,0x26,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_SECOND                                               0x0A,0x27,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_MILLISECOND                                          0x0A,0x28,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_TIMESTAMP                                            0x0A,0x29,0x05
+#define HID_USAGE_SENSOR_DATA_TIME_JULIAN_DAY_OF_YEAR                                   0x0A,0x2A,0x05
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY_TIME                                                  0x0A,0x30,0x05
+#define HID_USAGE_SENSOR_PROPERTY_TIME_TIME_ZONE_OFFSET_FROM_UTC                        0x0A,0x31,0x05
+#define HID_USAGE_SENSOR_PROPERTY_TIME_TIME_ZONE_NAME                                   0x0A,0x32,0x05
+#define HID_USAGE_SENSOR_PROPERTY_TIME_DAYLIGHT_SAVINGS_TIME_OBSERVED                   0x0A,0x33,0x05
+#define HID_USAGE_SENSOR_PROPERTY_TIME_TIME_TRIM_ADJUSTMENT                             0x0A,0x34,0x05
+#define HID_USAGE_SENSOR_PROPERTY_TIME_ARM_ALARM                                        0x0A,0x35,0x05
+
+//data type custom
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_CUSTOM                                                    0x0A,0x40,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_USAGE                                              0x0A,0x41,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_BOOLEAN_ARRAY                                      0x0A,0x42,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE                                              0x0A,0x43,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1                                            0x0A,0x44,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_2                                            0x0A,0x45,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_3                                            0x0A,0x46,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_4                                            0x0A,0x47,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_5                                            0x0A,0x48,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_6                                            0x0A,0x49,0x05
+
+#if 1 //define vendor-specific (non-spec) custom datafields
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_7                                            0x0A,0x4A,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_8                                            0x0A,0x4B,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_9                                            0x0A,0x4C,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_10                                           0x0A,0x4D,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_11                                           0x0A,0x4E,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_12                                           0x0A,0x4F,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_13                                           0x0A,0x50,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_14                                           0x0A,0x51,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_15                                           0x0A,0x52,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_16                                           0x0A,0x53,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_17                                           0x0A,0x54,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_18                                           0x0A,0x55,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_19                                           0x0A,0x56,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_20                                           0x0A,0x57,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_21                                           0x0A,0x58,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_22                                           0x0A,0x59,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_23                                           0x0A,0x5A,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_24                                           0x0A,0x5B,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_25                                           0x0A,0x5C,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_26                                           0x0A,0x5D,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_27                                           0x0A,0x5E,0x05
+#define HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_28                                           0x0A,0x5F,0x05
+#endif
+
+//data type generic
+//data field usages (input report)
+#define HID_USAGE_SENSOR_DATA_GENERIC                                                   0x0A,0x60,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_GUID_OR_PROPERTYKEY                               0x0A,0x61,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_CATEGORY_GUID                                     0x0A,0x62,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_TYPE_GUID                                         0x0A,0x63,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_EVENT_PROPERTYKEY                                 0x0A,0x64,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_PROPERTY_PROPERTYKEY                              0x0A,0x65,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_DATAFIELD_PROPERTYKEY                             0x0A,0x66,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_EVENT                                             0x0A,0x67,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_PROPERTY                                          0x0A,0x68,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_DATAFIELD                                         0x0A,0x69,0x05
+#define HID_USAGE_SENSOR_DATA_ENUMERATOR_TABLE_ROW_INDEX                                0x0A,0x6A,0x05
+#define HID_USAGE_SENSOR_DATA_ENUMERATOR_TABLE_ROW_COUNT                                0x0A,0x6B,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_GUID_OR_PROPERTYKEY_KIND                          0x0A,0x6C,0x05 // NAry
+//begin GorPK kind selectors
+#define HID_USAGE_SENSOR_GORPK_KIND_CATEGORY                                            0x0A,0xD0,0x08 // Sel
+#define HID_USAGE_SENSOR_GORPK_KIND_TYPE                                                0x0A,0xD1,0x08 // Sel
+#define HID_USAGE_SENSOR_GORPK_KIND_EVENT                                               0x0A,0xD2,0x08 // Sel
+#define HID_USAGE_SENSOR_GORPK_KIND_PROPERTY                                            0x0A,0xD3,0x08 // Sel
+#define HID_USAGE_SENSOR_GORPK_KIND_DATAFIELD                                           0x0A,0xD4,0x08 // Sel
+//end GorPK kind selectors
+#define HID_USAGE_SENSOR_DATA_GENERIC_GUID                                              0x0A,0x6D,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_PROPERTYKEY                                       0x0A,0x6E,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_TOP_LEVEL_COLLECTION_ID                           0x0A,0x6F,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_REPORT_ID                                         0x0A,0x70,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_REPORT_ITEM_POSITION_INDEX                        0x0A,0x71,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_FIRMWARE_VARTYPE                                  0x0A,0x72,0x05 // NAry
+//begin firmware vartype selectors
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_NULL                                       0x0A,0x00,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_BOOL                                       0x0A,0x01,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_UI1                                        0x0A,0x02,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_I1                                         0x0A,0x03,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_UI2                                        0x0A,0x04,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_I2                                         0x0A,0x05,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_UI4                                        0x0A,0x06,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_I4                                         0x0A,0x07,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_UI8                                        0x0A,0x08,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_I8                                         0x0A,0x09,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_R4                                         0x0A,0x0A,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_R8                                         0x0A,0x0B,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_WSTR                                       0x0A,0x0C,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_STR                                        0x0A,0x0D,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_CLSID                                      0x0A,0x0E,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_VECTOR_VT_UI1                              0x0A,0x0F,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E0                                      0x0A,0x10,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E1                                      0x0A,0x11,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E2                                      0x0A,0x12,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E3                                      0x0A,0x13,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E4                                      0x0A,0x14,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E5                                      0x0A,0x15,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E6                                      0x0A,0x16,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E7                                      0x0A,0x17,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E8                                      0x0A,0x18,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16E9                                      0x0A,0x19,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16EA                                      0x0A,0x1A,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16EB                                      0x0A,0x1B,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16EC                                      0x0A,0x1C,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16ED                                      0x0A,0x1D,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16EE                                      0x0A,0x1E,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F16EF                                      0x0A,0x1F,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E0                                      0x0A,0x20,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E1                                      0x0A,0x21,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E2                                      0x0A,0x22,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E3                                      0x0A,0x23,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E4                                      0x0A,0x24,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E5                                      0x0A,0x25,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E6                                      0x0A,0x26,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E7                                      0x0A,0x27,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E8                                      0x0A,0x28,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32E9                                      0x0A,0x29,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32EA                                      0x0A,0x2A,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32EB                                      0x0A,0x2B,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32EC                                      0x0A,0x2C,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32ED                                      0x0A,0x2D,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32EE                                      0x0A,0x2E,0x09 // Sel
+#define HID_USAGE_SENSOR_FIRMWARE_VARTYPE_VT_F32EF                                      0x0A,0x2F,0x09 // Sel
+//end firmware vartype selectors
+#define HID_USAGE_SENSOR_DATA_GENERIC_UNIT_OF_MEASURE                                   0x0A,0x73,0x05 // NAry
+//begin unit of measure selectors
+#define HID_USAGE_SENSOR_GENERIC_UNIT_NOT_SPECIFIED                                     0x0A,0x40,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_LUX                                               0x0A,0x41,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_DEGREES_KELVIN                                    0x0A,0x42,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_DEGREES_CELSIUS                                   0x0A,0x43,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_PASCAL                                            0x0A,0x44,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_NEWTON                                            0x0A,0x45,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_METERS_PER_SECOND                                 0x0A,0x46,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_KILOGRAM                                          0x0A,0x47,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_METER                                             0x0A,0x48,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_METERS_PER_SEC_SQRD                               0x0A,0x49,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_FARAD                                             0x0A,0x4A,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_AMPERE                                            0x0A,0x4B,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_WATT                                              0x0A,0x4C,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_HENRY                                             0x0A,0x4D,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_OHM                                               0x0A,0x4E,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_VOLT                                              0x0A,0x4F,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_HERTZ                                             0x0A,0x50,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_BAR                                               0x0A,0x51,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_DEGREES_ANTI_CLOCKWISE                            0x0A,0x52,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_DEGREES_CLOCKWISE                                 0x0A,0x53,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_DEGREES                                           0x0A,0x54,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_DEGREES_PER_SECOND                                0x0A,0x55,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_DEGREES_PER_SEC_SQRD                              0x0A,0x56,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_KNOT                                              0x0A,0x57,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_PERCENT                                           0x0A,0x58,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_SECOND                                            0x0A,0x59,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_MILLISECOND                                       0x0A,0x5A,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_G                                                 0x0A,0x5B,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_BYTES                                             0x0A,0x5C,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_MILLIGAUSS                                        0x0A,0x5D,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_UNIT_BITS                                              0x0A,0x5E,0x09 // Sel
+//end unit of measure selectors
+#define HID_USAGE_SENSOR_DATA_GENERIC_UNIT_EXPONENT                                     0x0A,0x74,0x05 // NAry
+//begin unit exponent selectors
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_0                                             0x0A,0x70,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_1                                             0x0A,0x71,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_2                                             0x0A,0x72,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_3                                             0x0A,0x73,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_4                                             0x0A,0x74,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_5                                             0x0A,0x75,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_6                                             0x0A,0x76,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_7                                             0x0A,0x77,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_8                                             0x0A,0x78,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_9                                             0x0A,0x79,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_A                                             0x0A,0x7A,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_B                                             0x0A,0x7B,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_C                                             0x0A,0x7C,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_D                                             0x0A,0x7D,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_E                                             0x0A,0x7E,0x09 // Sel
+#define HID_USAGE_SENSOR_GENERIC_EXPONENT_F                                             0x0A,0x7F,0x09 // Sel
+//end unit exponent selectors
+#define HID_USAGE_SENSOR_DATA_GENERIC_REPORT_SIZE                                       0x0A,0x75,0x05
+#define HID_USAGE_SENSOR_DATA_GENERIC_REPORT_COUNT                                      0x0A,0x76,0x05
+//property usages (get/set feature report)
+#define HID_USAGE_SENSOR_PROPERTY_GENERIC                                               0x0A,0x80,0x05
+#define HID_USAGE_SENSOR_PROPERTY_ENUMERATOR_TABLE_ROW_INDEX                            0x0A,0x81,0x05
+#define HID_USAGE_SENSOR_PROPERTY_ENUMERATOR_TABLE_ROW_COUNT                            0x0A,0x82,0x05
+
+
+////////////////////////////////////////////////////////////////////////////////////
+//
+// Other HID definitions
+//
+////////////////////////////////////////////////////////////////////////////////////
+
+//NOTE: These definitions are designed to permit compiling the HID report descriptors
+// with somewhat self-explanatory information to help readability and reduce errors
+
+//input,output,feature flags
+#define Data_Arr_Abs                            0x00
+#define Const_Arr_Abs                           0x01
+#define Data_Var_Abs                            0x02
+#define Const_Var_Abs                           0x03
+#define Data_Var_Rel                            0x06
+//collection flags
+#define Physical                                0x00
+#define Application                             0x01
+#define Logical                                 0x02
+#define NamedArray                              0x04
+#define UsageSwitch                             0x05
+//other
+#define Undefined                               0x00
+
+#define HID_USAGE_PAGE(a)                       0x05,a
+#define HID_USAGE(a)                            0x09,a
+#define HID_USAGE16(a,b)                        0x0A,a,b
+#define HID_USAGE_SENSOR_DATA(a,b)              a|b     //This or-s the mod into usage
+#define HID_COLLECTION(a)                       0xA1,a
+#define HID_REPORT_ID(a)                        0x85,a
+#define HID_REPORT_SIZE(a)                      0x75,a
+#define HID_REPORT_COUNT(a)                     0x95,a
+#define HID_USAGE_MIN_8(a)                      0x19,a
+#define HID_USAGE_MIN_16(a,b)                   0x1A,a,b
+#define HID_USAGE_MAX_8(a)                      0x29,a
+#define HID_USAGE_MAX_16(a,b)                   0x2A,a,b
+#define HID_LOGICAL_MIN_8(a)                    0x15,a
+#define HID_LOGICAL_MIN_16(a,b)                 0x16,a,b
+#define HID_LOGICAL_MIN_32(a,b,c,d)             0x17,a,b,c,d
+#define HID_LOGICAL_MAX_8(a)                    0x25,a
+#define HID_LOGICAL_MAX_16(a,b)                 0x26,a,b
+#define HID_LOGICAL_MAX_32(a,b,c,d)             0x27,a,b,c,d
+#define HID_UNIT_EXPONENT(a)                    0x55,a
+#define HID_INPUT(a)                            0x81,a
+#define HID_OUTPUT(a)                           0x91,a
+#define HID_FEATURE(a)                          0xB1,a
+#define HID_END_COLLECTION                      0xC0
+
+#endif // HIDUTIL_TEST_HIDSENSORSPEC_H
diff --git a/modules/sensors/dynamic_sensor/HidUtils/test/TriStateTest.cpp b/modules/sensors/dynamic_sensor/HidUtils/test/TriStateTest.cpp
new file mode 100644
index 0000000..9dcdf0b
--- /dev/null
+++ b/modules/sensors/dynamic_sensor/HidUtils/test/TriStateTest.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "TriState.h"
+#include <gtest/gtest.h>
+
+#include <cassert>
+#include <cstdint>
+#include <cstdio>
+#include <iostream>
+
+using HidUtil::TriState;
+typedef TriState<uint32_t> tri_uint32_t;
+typedef TriState<int32_t> tri_int32_t;
+typedef TriState<int16_t> tri_int16_t;
+
+TEST(TriStateTest, Constructor) {
+    tri_uint32_t a;
+    EXPECT_FALSE(a.isSet());
+
+    a += 1;
+    EXPECT_FALSE(a.isSet());
+
+    a -= 1;
+    EXPECT_FALSE(a.isSet());
+
+    a *= 1;
+    EXPECT_FALSE(a.isSet());
+
+    a /= 1;
+    EXPECT_FALSE(a.isSet());
+
+    tri_uint32_t b;
+    b = a;
+    EXPECT_FALSE(b.isSet());
+
+    a = 1;
+    EXPECT_TRUE(a.isSet());
+
+    b = a;
+    EXPECT_TRUE(b.isSet());
+
+    a.clear();
+    EXPECT_FALSE(a.isSet());
+    EXPECT_TRUE(b.isSet());
+
+    tri_uint32_t c(b);
+    EXPECT_TRUE(c.isSet());
+
+    c.clear();
+    EXPECT_FALSE(c.isSet());
+
+    tri_uint32_t d(a);
+    EXPECT_FALSE(c.isSet());
+}
+
+TEST(TriStateTest, IncAndDecOperation) {
+    tri_int32_t a(1);
+
+    EXPECT_EQ(2, (++a).get(0));
+    EXPECT_EQ(2, (a++).get(0));
+    EXPECT_EQ(3, a.get(0));
+
+    EXPECT_EQ(2, (--a).get(0));
+    EXPECT_EQ(2, (a--).get(0));
+    EXPECT_EQ(1, a.get(0));
+
+    tri_uint32_t b;
+    EXPECT_EQ(static_cast<uint32_t>(100), (++b).get(100));
+    EXPECT_EQ(static_cast<uint32_t>(101), (b++).get(101));
+    EXPECT_EQ(static_cast<uint32_t>(102), b.get(102));
+    EXPECT_FALSE(b.isSet());
+
+    EXPECT_EQ(static_cast<uint32_t>(103), (--b).get(103));
+    EXPECT_EQ(static_cast<uint32_t>(104), (b--).get(104));
+    EXPECT_EQ(static_cast<uint32_t>(105), b.get(105));
+    EXPECT_FALSE(b.isSet());
+}
+
+TEST(TriStateTest, Comparison) {
+    tri_int32_t a(1);
+    tri_int32_t b(1);
+    tri_int32_t c(2);
+    tri_int32_t d;
+
+    EXPECT_EQ(a, b);
+    EXPECT_FALSE((a != b));
+    EXPECT_TRUE(!(a != b));
+    EXPECT_NE(-1, a);
+
+    EXPECT_LT(a, c);
+    EXPECT_LT(a, 3);
+
+    EXPECT_GT(c, b);
+    EXPECT_GT(c, 0);
+
+    EXPECT_LE(a, 1);
+    EXPECT_LE(a, c);
+    EXPECT_LE(a, 3);
+    EXPECT_LE(a, b);
+
+    EXPECT_GE(c, b);
+    EXPECT_GE(b, a);
+    EXPECT_GE(c, 0);
+    EXPECT_GE(c, 2);
+
+    EXPECT_FALSE((a == d).isSet());
+    EXPECT_FALSE((a >= d).isSet());
+    EXPECT_FALSE((a <= d).isSet());
+    EXPECT_FALSE((a != d).isSet());
+    EXPECT_FALSE((a > d).isSet());
+    EXPECT_FALSE((a < d).isSet());
+
+    //EXPECT_EQ(a, d); // will cause runtime failure
+    // due to converting a not-set TriState<bool> to bool
+}
+
+TEST(TriStateTest, CompoundAssign) {
+    tri_uint32_t x;
+
+    x += 10;
+    EXPECT_FALSE(x.isSet());
+    x -= 10;
+    EXPECT_FALSE(x.isSet());
+    x *= 10;
+    EXPECT_FALSE(x.isSet());
+    x /= 10;
+    EXPECT_FALSE(x.isSet());
+    x &= 10;
+    EXPECT_FALSE(x.isSet());
+    x |= 10;
+    EXPECT_FALSE(x.isSet());
+    x %= 10;
+    EXPECT_FALSE(x.isSet());
+    x <<= 10;
+    EXPECT_FALSE(x.isSet());
+    x >>= 10;
+    EXPECT_FALSE(x.isSet());
+
+    tri_int32_t y, z, w;
+#define TEST_COMPOUND_ASSIGN(a, op, op_c, b) \
+    y = z = a; \
+    w = b; \
+    y op_c b; \
+    EXPECT_TRUE(y.isSet()); \
+    EXPECT_EQ(y, (a op b)); \
+    EXPECT_EQ(y, (z op b)); \
+    EXPECT_EQ(y, (a op w));
+
+    TEST_COMPOUND_ASSIGN(123, +, +=, 456);
+    TEST_COMPOUND_ASSIGN(123, -, -=, 456);
+    TEST_COMPOUND_ASSIGN(123, *, *=, 456);
+    TEST_COMPOUND_ASSIGN(123, /, /=, 456);
+    TEST_COMPOUND_ASSIGN(123, |, |=, 456);
+    TEST_COMPOUND_ASSIGN(123, &, &=, 456);
+    TEST_COMPOUND_ASSIGN(123, ^, ^=, 456);
+    TEST_COMPOUND_ASSIGN(123, %, %=, 456);
+#undef TEST_COMPOUND_ASSIGN
+    y = z = 123;
+    w = 10;
+    y <<= 10;
+    EXPECT_TRUE(y.isSet());
+    EXPECT_EQ(123 << 10, y);
+
+    y = z = 12345;
+    w = 10;
+    y >>= 10;
+    EXPECT_TRUE(y.isSet());
+    EXPECT_EQ(12345 >> 10, y);
+}
+
+TEST(TriStateTest, UnaryOperation) {
+    tri_int16_t p;
+    EXPECT_FALSE((!p).isSet());
+    EXPECT_FALSE((-p).isSet());
+    EXPECT_FALSE((~p).isSet());
+
+    tri_int16_t q(1234);
+    EXPECT_TRUE((!q).isSet());
+    EXPECT_EQ(!static_cast<int16_t>(1234), (!q));
+
+    tri_int16_t r(1234);
+    EXPECT_TRUE((-r).isSet());
+    EXPECT_EQ(-1234, (-r));
+
+    tri_int16_t s(1234);
+    EXPECT_TRUE((~s).isSet());
+    EXPECT_EQ(~static_cast<int16_t>(1234), ~s);
+}
+