1 /*
2  *
3  * Copyright 2019, The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef TEEUI_COMMONMESSAGETYPES_H_
19 #define TEEUI_COMMONMESSAGETYPES_H_
20 
21 #include <teeui/msg_formatting.h>
22 
23 #include <tuple>
24 
25 #include <stdint.h>
26 
27 #include <teeui/static_vec.h>
28 
29 namespace teeui {
30 
31 enum class UIOption : uint32_t;
32 enum class ResponseCode : uint32_t;
33 enum class MessageSize : uint32_t;
34 enum class TestKeyBits : uint8_t;
35 enum class TestModeCommands : uint64_t;
36 
37 enum class UIOption : uint32_t {
38     AccessibilityInverted = 0u,
39     AccessibilityMagnified = 1u,
40 };
41 
42 enum class ResponseCode : uint32_t {
43     OK = 0u,
44     Canceled = 1u,
45     Aborted = 2u,
46     OperationPending = 3u,
47     Ignored = 4u,
48     SystemError = 5u,
49     Unimplemented = 6u,
50     Unexpected = 7u,
51     UIError = 0x10000,
52     UIErrorMissingGlyph,
53     UIErrorMessageTooLong,
54     UIErrorMalformedUTF8Encoding,
55 };
56 
57 enum class MessageSize : uint32_t {
58     MAX = 6144u,
59 };
60 
61 enum class TestKeyBits : uint8_t {
62     BYTE = 165,
63 };
64 
65 enum class TestModeCommands : uint64_t {
66     OK_EVENT = 0ull,
67     CANCEL_EVENT = 1ull,
68 };
69 
70 using MsgString = static_vec<const char>;
71 template <typename T> using MsgVector = static_vec<T>;
72 
copyField(T & field,const uint8_t * (& pos))73 template <typename T> inline const uint8_t* copyField(T& field, const uint8_t*(&pos)) {
74     auto& s = bytesCast(field);
75     std::copy(pos, pos + sizeof(T), s);
76     return pos + sizeof(T);
77 }
78 
copyField(const T & field,uint8_t * (& pos))79 template <typename T> inline uint8_t* copyField(const T& field, uint8_t*(&pos)) {
80     auto& s = bytesCast(field);
81     return std::copy(s, &s[sizeof(T)], pos);
82 }
83 
84 /**
85  * This actually only reads in place if compiled without TEEUI_USE_STD_VECTOR. See static_vec.h
86  * If compiled with TEEUI_USE_STD_VECTOR MsgVector becomes std::vector and the data is actually
87  * copied.
88  */
readSimpleVecInPlace(ReadStream in)89 template <typename T> std::tuple<ReadStream, MsgVector<T>> readSimpleVecInPlace(ReadStream in) {
90     std::tuple<ReadStream, MsgVector<T>> result;
91     ReadStream::ptr_t pos = nullptr;
92     size_t read_size = 0;
93     std::tie(std::get<0>(result), pos, read_size) = read(in);
94     if (!std::get<0>(result) || read_size % sizeof(T)) {
95         std::get<0>(result).bad();
96         return result;
97     }
98     std::get<1>(result) =
99         MsgVector<T>(reinterpret_cast<T*>(const_cast<uint8_t*>(pos)),
100                      reinterpret_cast<T*>(const_cast<uint8_t*>(pos)) + (read_size / sizeof(T)));
101     return result;
102 }
103 
writeSimpleVec(WriteStream out,const MsgVector<T> & vec)104 template <typename T> WriteStream writeSimpleVec(WriteStream out, const MsgVector<T>& vec) {
105     return write(out, reinterpret_cast<const uint8_t*>(vec.data()), vec.size() * sizeof(T));
106 }
107 
108 // ResponseCode
read(Message<ResponseCode>,ReadStream in)109 inline std::tuple<ReadStream, ResponseCode> read(Message<ResponseCode>, ReadStream in) {
110     return readSimpleType<ResponseCode>(in);
111 }
write(WriteStream out,const ResponseCode & v)112 inline WriteStream write(WriteStream out, const ResponseCode& v) {
113     return write(out, bytesCast(v));
114 }
115 
116 // TestModeCommands
read(Message<TestModeCommands>,ReadStream in)117 inline std::tuple<ReadStream, TestModeCommands> read(Message<TestModeCommands>, ReadStream in) {
118     return readSimpleType<TestModeCommands>(in);
119 }
write(WriteStream out,const TestModeCommands & v)120 inline WriteStream write(WriteStream out, const TestModeCommands& v) {
121     return write(out, bytesCast(v));
122 }
123 
124 namespace msg {
125 
126 // MsgVector<uint8_t>
read(Message<MsgVector<uint8_t>>,ReadStream in)127 inline std::tuple<ReadStream, MsgVector<uint8_t>> read(Message<MsgVector<uint8_t>>, ReadStream in) {
128     return readSimpleVecInPlace<uint8_t>(in);
129 }
write(WriteStream out,const MsgVector<uint8_t> & v)130 inline WriteStream write(WriteStream out, const MsgVector<uint8_t>& v) {
131     return writeSimpleVec(out, v);
132 }
133 
134 // MsgString
read(Message<MsgString>,ReadStream in)135 inline std::tuple<ReadStream, MsgString> read(Message<MsgString>, ReadStream in) {
136     return readSimpleVecInPlace<const char>(in);
137 }
write(WriteStream out,const MsgString & v)138 inline WriteStream write(WriteStream out, const MsgString& v) {
139     return writeSimpleVec(out, v);
140 }
141 
142 // MsgVector<UIOption>
read(Message<MsgVector<UIOption>>,ReadStream in)143 inline std::tuple<ReadStream, MsgVector<UIOption>> read(Message<MsgVector<UIOption>>,
144                                                         ReadStream in) {
145     return readSimpleVecInPlace<UIOption>(in);
146 }
write(WriteStream out,const MsgVector<UIOption> & v)147 inline WriteStream write(WriteStream out, const MsgVector<UIOption>& v) {
148     return writeSimpleVec(out, v);
149 }
150 
151 }  //  namespace msg
152 
153 // teeui::Array<uint8_t, size>
154 template <size_t size>
155 inline std::tuple<teeui::ReadStream, teeui::Array<uint8_t, size>>
read(teeui::Message<teeui::Array<uint8_t,size>>,teeui::ReadStream in)156 read(teeui::Message<teeui::Array<uint8_t, size>>, teeui::ReadStream in) {
157     std::tuple<teeui::ReadStream, teeui::Array<uint8_t, size>> result;
158     teeui::ReadStream& in_ = std::get<0>(result);
159     auto& result_ = std::get<1>(result);
160     teeui::ReadStream::ptr_t pos = nullptr;
161     size_t read_size = 0;
162     std::tie(in_, pos, read_size) = read(in);
163     if (!in_) return result;
164     if (read_size != size) {
165         in_.bad();
166         return result;
167     }
168     std::copy(pos, pos + size, result_.data());
169     return result;
170 }
171 template <size_t size>
write(teeui::WriteStream out,const teeui::Array<uint8_t,size> & v)172 inline teeui::WriteStream write(teeui::WriteStream out, const teeui::Array<uint8_t, size>& v) {
173     return write(out, v.data(), v.size());
174 }
175 
176 }  // namespace teeui
177 
178 #endif  // TEEUI_COMMONMESSAGETYPES_H_
179