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_GENERICMESSAGES_H_
19 #define TEEUI_GENERICMESSAGES_H_
20
21 #include <limits>
22 #include <tuple>
23
24 #include <stdint.h>
25
26 #include <teeui/common_message_types.h>
27 #include <teeui/msg_formatting.h>
28
29 namespace teeui {
30
31 enum class Command : uint32_t {
32 Invalid,
33 PromptUserConfirmation,
34 FetchConfirmationResult,
35 DeliverTestCommand,
36 Abort,
37 };
38
39 using Protocol = uint32_t;
40
41 template <Protocol Proto, typename CmdT, CmdT cmd> struct Cmd {};
42
43 static constexpr const Protocol kProtoGeneric = 0;
44 static constexpr const Protocol kProtoInvalid = std::numeric_limits<Protocol>::max();
45
46 #define DECLARE_GENERIC_COMMAND(cmd) using Cmd##cmd = Cmd<kProtoGeneric, Command, Command::cmd>
47
48 DECLARE_GENERIC_COMMAND(PromptUserConfirmation);
49 DECLARE_GENERIC_COMMAND(FetchConfirmationResult);
50 DECLARE_GENERIC_COMMAND(DeliverTestCommand);
51 DECLARE_GENERIC_COMMAND(Abort);
52
53 using PromptUserConfirmationMsg = Message<CmdPromptUserConfirmation, MsgString, MsgVector<uint8_t>,
54 MsgString, MsgVector<UIOption>>;
55 using PromptUserConfirmationResponse = Message<ResponseCode>;
56 using DeliverTestCommandMessage = Message<CmdDeliverTestCommand, TestModeCommands>;
57 using DeliverTestCommandResponse = Message<ResponseCode>;
58 using AbortMsg = Message<CmdAbort>;
59 using ResultMsg = Message<ResponseCode, MsgVector<uint8_t>, MsgVector<uint8_t>>;
60 using FetchConfirmationResult = Message<CmdFetchConfirmationResult>;
61
62 template <uint32_t proto, typename CmdT, CmdT cmd>
write(WriteStream out,Cmd<proto,CmdT,cmd>)63 inline WriteStream write(WriteStream out, Cmd<proto, CmdT, cmd>) {
64 volatile Protocol* protoptr = reinterpret_cast<volatile Protocol*>(out.pos());
65 out += sizeof(Protocol);
66 if (out) *protoptr = proto;
67
68 volatile CmdT* cmdptr = reinterpret_cast<volatile CmdT*>(out.pos());
69 out += sizeof(CmdT);
70 if (out) *cmdptr = cmd;
71
72 return out;
73 }
74
75 template <typename CmdSpec, typename... Tail>
write(Message<CmdSpec,Tail...>,WriteStream out,const Tail &...tail)76 WriteStream write(Message<CmdSpec, Tail...>, WriteStream out, const Tail&... tail) {
77 out = write(out, CmdSpec());
78 return write(Message<Tail...>(), out, tail...);
79 }
80
81 template <Protocol proto, typename CmdT, CmdT cmd, typename... Fields>
read(Message<Cmd<proto,CmdT,cmd>,Fields...>,ReadStream in)82 std::tuple<ReadStream, Fields...> read(Message<Cmd<proto, CmdT, cmd>, Fields...>, ReadStream in) {
83 return read(Message<Fields...>(), in);
84 }
85
86 template <Protocol proto, typename CmdT, CmdT cmd, typename... T>
87 struct msg2tuple<Message<Cmd<proto, CmdT, cmd>, T...>> {
88 using type = std::tuple<T...>;
89 };
90
91 std::tuple<ReadStream, uint32_t> readU32(ReadStream in);
92
93 template <typename CmdT, CmdT Invalid = CmdT::Invalid>
94 std::tuple<ReadStream, CmdT> readCmd(ReadStream in) {
95 static_assert(sizeof(CmdT) == sizeof(uint32_t),
96 "Can only be used with types the size of uint32_t");
97 auto [stream, value] = readU32(in);
98 if (stream) return {stream, CmdT(value)};
99 return {stream, Invalid};
100 }
101
102 template <typename CmdT, CmdT Invalid = CmdT::Invalid> CmdT peakCmd(ReadStream in) {
103 auto [_, cmd] = readCmd<CmdT>(in);
104 return cmd;
105 }
106
107 std::tuple<ReadStream, Command> readCommand(ReadStream in);
108 Command peakCommand(ReadStream in);
109 std::tuple<ReadStream, Protocol> readProtocol(ReadStream in);
110 Protocol peakProtocol(ReadStream in);
111
112 } // namespace teeui
113
114 #endif // TEEUI_GENERICMESSAGES_H_
115