summaryrefslogtreecommitdiffstats
path: root/device/hid/hid_report_descriptor_item.h
blob: d3392330709e6d3928b2a2cc3b4f54b2fa61acb0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef DEVICE_HID_HID_REPORT_DESCRIPTOR_ITEM_H_
#define DEVICE_HID_HID_REPORT_DESCRIPTOR_ITEM_H_

#include "base/basictypes.h"

namespace device {

// An element of a HID report descriptor.
class HidReportDescriptorItem {
 private:
  friend class HidReportDescriptor;

  enum Type {
    kTypeMain = 0,
    kTypeGlobal = 1,
    kTypeLocal = 2,
    kTypeReserved = 3
  };

  enum MainTag {
    kMainTagDefault = 0x00,       // 0000
    kMainTagInput = 0x08,         // 1000
    kMainTagOutput = 0x09,        // 1001
    kMainTagFeature = 0x0B,       // 1011
    kMainTagCollection = 0x0A,    // 1010
    kMainTagEndCollection = 0x0C  // 1100
  };

  enum GlobalTag {
    kGlobalTagUsagePage = 0x00,        // 0000
    kGlobalTagLogicalMinimum = 0x01,   // 0001
    kGlobalTagLogicalMaximum = 0x02,   // 0010
    kGlobalTagPhysicalMinimum = 0x03,  // 0011
    kGlobalTagPhysicalMaximum = 0x04,  // 0100
    kGlobalTagUnitExponent = 0x05,     // 0101
    kGlobalTagUnit = 0x06,             // 0110
    kGlobalTagReportSize = 0x07,       // 0111
    kGlobalTagReportId = 0x08,         // 1000
    kGlobalTagReportCount = 0x09,      // 1001
    kGlobalTagPush = 0x0A,             // 1010
    kGlobalTagPop = 0x0B               // 1011
  };

  enum LocalTag {
    kLocalTagUsage = 0x00,              // 0000
    kLocalTagUsageMinimum = 0x01,       // 0001
    kLocalTagUsageMaximum = 0x02,       // 0010
    kLocalTagDesignatorIndex = 0x03,    // 0011
    kLocalTagDesignatorMinimum = 0x04,  // 0100
    kLocalTagDesignatorMaximum = 0x05,  // 0101
    kLocalTagStringIndex = 0x07,        // 0111
    kLocalTagStringMinimum = 0x08,      // 1000
    kLocalTagStringMaximum = 0x09,      // 1001
    kLocalTagDelimiter = 0x0A           // 1010
  };

  enum ReservedTag {
    kReservedTagLong = 0xF  // 1111
  };

 public:
  enum Tag {
    kTagDefault = kMainTagDefault << 2 | kTypeMain,
    kTagInput = kMainTagInput << 2 | kTypeMain,
    kTagOutput = kMainTagOutput << 2 | kTypeMain,
    kTagFeature = kMainTagFeature << 2 | kTypeMain,
    kTagCollection = kMainTagCollection << 2 | kTypeMain,
    kTagEndCollection = kMainTagEndCollection << 2 | kTypeMain,
    kTagUsagePage = kGlobalTagUsagePage << 2 | kTypeGlobal,
    kTagLogicalMinimum = kGlobalTagLogicalMinimum << 2 | kTypeGlobal,
    kTagLogicalMaximum = kGlobalTagLogicalMaximum << 2 | kTypeGlobal,
    kTagPhysicalMinimum = kGlobalTagPhysicalMinimum << 2 | kTypeGlobal,
    kTagPhysicalMaximum = kGlobalTagPhysicalMaximum << 2 | kTypeGlobal,
    kTagUnitExponent = kGlobalTagUnitExponent << 2 | kTypeGlobal,
    kTagUnit = kGlobalTagUnit << 2 | kTypeGlobal,
    kTagReportSize = kGlobalTagReportSize << 2 | kTypeGlobal,
    kTagReportId = kGlobalTagReportId << 2 | kTypeGlobal,
    kTagReportCount = kGlobalTagReportCount << 2 | kTypeGlobal,
    kTagPush = kGlobalTagPush << 2 | kTypeGlobal,
    kTagPop = kGlobalTagPop << 2 | kTypeGlobal,
    kTagUsage = kLocalTagUsage << 2 | kTypeLocal,
    kTagUsageMinimum = kLocalTagUsageMinimum << 2 | kTypeLocal,
    kTagUsageMaximum = kLocalTagUsageMaximum << 2 | kTypeLocal,
    kTagDesignatorIndex = kLocalTagDesignatorIndex << 2 | kTypeLocal,
    kTagDesignatorMinimum = kLocalTagDesignatorMinimum << 2 | kTypeLocal,
    kTagDesignatorMaximum = kLocalTagDesignatorMaximum << 2 | kTypeLocal,
    kTagStringIndex = kLocalTagStringIndex << 2 | kTypeLocal,
    kTagStringMinimum = kLocalTagStringMinimum << 2 | kTypeLocal,
    kTagStringMaximum = kLocalTagStringMaximum << 2 | kTypeLocal,
    kTagDelimiter = kLocalTagDelimiter << 2 | kTypeLocal,
    kTagLong = kReservedTagLong << 2 | kTypeReserved
  };

  // HID Input/Output/Feature report information.
  // Can be retrieved from GetShortData()
  // when item.tag() == HidReportDescriptorItem::kTagInput
  // or HidReportDescriptorItem::kTagOutput
  // or HidReportDescriptorItem::kTagFeature
  struct ReportInfo {
    uint8_t data_or_constant : 1;
    uint8_t array_or_variable : 1;
    uint8_t absolute_or_relative : 1;
    uint8_t wrap : 1;
    uint8_t linear : 1;
    uint8_t preferred : 1;
    uint8_t null : 1;
    uint8_t reserved_1 : 1;
    uint8_t bit_field_or_buffer : 1;
    uint8_t reserved_2 : 1;
  };

  // HID collection type.
  // Can be retrieved from GetShortData()
  // when item.tag() == HidReportDescriptorItem::kTagCollection
  enum CollectionType {
    kCollectionTypePhysical,
    kCollectionTypeApplication,
    kCollectionTypeLogical,
    kCollectionTypeReport,
    kCollectionTypeNamedArray,
    kCollectionTypeUsageSwitch,
    kCollectionTypeUsageModifier,
    kCollectionTypeReserved,
    kCollectionTypeVendor
  };

 private:
  HidReportDescriptorItem(const uint8_t* bytes,
                          HidReportDescriptorItem* previous);

 public:
  ~HidReportDescriptorItem() {}

  // Previous element in report descriptor.
  // Owned by descriptor instance.
  HidReportDescriptorItem* previous() const {
    return previous_;
  };
  // Next element in report descriptor.
  // Owned by descriptor instance.
  HidReportDescriptorItem* next() const {
    return next_;
  };
  // Parent element in report descriptor.
  // Owned by descriptor instance.
  // Can be NULL.
  HidReportDescriptorItem* parent() const {
    return parent_;
  };
  // Level in Parent-Children relationship tree.
  // 0 for top-level items (parent()==NULL).
  // 1 if parent() is top-level.
  // 2 if parent() has a top-level parent. Etc.
  size_t GetDepth() const;
  Tag tag() const { return tag_; }
  // Returns true for a long item, false otherwise.
  bool IsLong() const;
  // Raw data of a short item.
  // Not valid for a long item.
  uint32_t GetShortData() const;

  static CollectionType GetCollectionTypeFromValue(uint32_t value);

 private:
  size_t GetHeaderSize() const;
  size_t payload_size() const { return payload_size_; }
  size_t GetSize() const;

  HidReportDescriptorItem* previous_;
  HidReportDescriptorItem* next_;
  HidReportDescriptorItem* parent_;
  Tag tag_;
  uint32_t shortData_;
  size_t payload_size_;
};

}  // namespace device

#endif  // DEVICE_HID_HID_REPORT_DESCRIPTOR_ITEM_H_