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