1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef NANOMESSAGE_H_
18 #define NANOMESSAGE_H_
19 
20 #include <memory>
21 #include <string>
22 #include <vector>
23 
24 #include "noncopyable.h"
25 
26 namespace android {
27 
28 /*
29  * Events types that can be pushed back and forth between the ContextHub and
30  * host software.
31  */
32 enum class EventType {
33     FirstSensorEvent = 0x00000200,
34     LastSensorEvent  = 0x000002FF,
35     ConfigureSensor  = 0x00000300,
36     AppToHostEvent   = 0x00000401,
37     ResetReasonEvent = 0x00000403,
38 };
39 
40 /*
41  * An interface for all messages passed to and from the ContextHub.
42  */
43 class NanoMessage : public NonCopyable {
44   public:
~NanoMessage()45     virtual ~NanoMessage() {};
46 
47     // Generates a string intended to be printed to a console or saved to logs.
48     // This interface requires that the string be terminated with a newline.
49     virtual std::string ToString() const = 0;
50 };
51 
52 /*
53  * An interface for requests sent to the ContextHub.
54  */
55 class NanoRequest : public NanoMessage {
56   public:
57     // Returns a payload of bytes to be packaged into a NanoPacket.
58     virtual std::vector<uint8_t> GetBytes() const = 0;
59 };
60 
61 /*
62  * An interface for responses from the ContextHub.
63  */
64 class NanoResponse : public NanoMessage {
65   public:
66     // Populates the fields of the NanoMessage given a NanoPacket. Returns
67     // false if the packet is incomplete or incorrect message.
68     virtual bool Populate(const std::vector<uint8_t>& buffer) = 0;
69 };
70 
71 /*
72  * Version information for a ContextHub.
73  */
74 class HardwareVersionInfo : public NanoResponse {
75   public:
76     bool Populate(const std::vector<uint8_t>& buffer) override;
77     std::string ToString() const override;
78 
79     struct VersionInfo {
80         uint16_t hardware_type;
81         uint16_t hardware_version;
82         uint16_t bootloader_version;
83         uint16_t operating_system_version;
84         uint32_t variant_version;
85     } __attribute__((packed)) info;
86 };
87 
88 /*
89  * The base event for all event data.
90  */
91 struct Event {
92     uint32_t event_type;
93 } __attribute__((packed));
94 
95 /*
96  * A request to write an event to the ContextHub.
97  */
98 class WriteEventRequest : public NanoRequest {
99   public:
100     virtual EventType GetEventType() const = 0;
101 };
102 
103 /*
104  * A response to writing an event to the ContextHub.
105  */
106 class WriteEventResponse : public NanoResponse {
107   public:
108     std::string ToString() const override;
109     bool Populate(const std::vector<uint8_t>& buffer) override;
110 
111     struct Response {
112         bool accepted;
113     } __attribute__((packed)) response;
114 };
115 
116 /*
117  * A response to reading an event from the ContextHub.
118  */
119 class ReadEventRequest : public NanoRequest {
120   public:
121     std::vector<uint8_t> GetBytes() const override;
122     std::string ToString() const override;
123 
124     struct Request {
125         uint64_t boot_time;
126     } __attribute__((packed)) request;
127 };
128 
129 class ReadEventResponse : public NanoResponse {
130   public:
131     virtual std::string ToString() const override;
132 
133     // Construct and populate a concrete ReadEventResponse from the given buffer
134     static std::unique_ptr<ReadEventResponse> FromBytes(
135         const std::vector<uint8_t>& buffer);
136 
137     bool Populate(const std::vector<uint8_t>& buffer) override;
138 
139     bool IsAppToHostEvent() const;
140     bool IsSensorEvent() const;
141     bool IsResetReasonEvent() const;
142     uint32_t GetEventType() const;
143 
144     // Event data associated with this response.
145     std::vector<uint8_t> event_data;
146 
147   protected:
148     static uint32_t EventTypeFromBuffer(const std::vector<uint8_t>& buffer);
149     static bool IsAppToHostEvent(uint32_t event_type);
150     static bool IsSensorEvent(uint32_t event_type);
151     static bool IsResetReasonEvent(uint32_t event_type);
152 };
153 
154 /*
155  * An event used to configure a sensor with specific attributes.
156  */
157 class ConfigureSensorRequest : public WriteEventRequest {
158   public:
159     enum class CommandType {
160         Disable,
161         Enable,
162         Flush,
163         ConfigData,
164         Calibrate
165     };
166 
167     ConfigureSensorRequest();
168 
169     static uint32_t FloatRateToFixedPoint(float rate);
170     static float FixedPointRateToFloat(uint32_t rate);
171 
172     std::vector<uint8_t> GetBytes() const override;
173     std::string ToString() const override;
174     EventType GetEventType() const override;
175 
176     // Appends some data to the configuration request, e.g. for the ConfigData
177     // command
178     void SetAdditionalData(const std::vector<uint8_t>& data);
179 
180     struct Configuration : public Event {
181         uint64_t latency;
182         uint32_t rate;
183         uint8_t sensor_type;
184         uint8_t command;
185         uint16_t flags;
186     }  __attribute__((packed)) config = {};
187 
188   private:
189     std::vector<uint8_t> extra_data_;
190 };
191 
192 }  // namespace android
193 
194 #endif  // NANOMESSAGE_H_
195