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#include <nvram/messages/nvram_messages.h>
18
19#include <nvram/messages/blob.h>
20#include <nvram/messages/io.h>
21#include <nvram/messages/proto.hpp>
22
23namespace nvram {
24
25// Descriptors for the message types.
26
27// IMPORTANT: The field numbers specified here correspond to protocol buffer
28// fields on the wire. While they are arbitrary, they should never be
29// reordered, reassigned, or overloaded once defined.
30template<> struct DescriptorForType<GetInfoRequest> {
31  static constexpr auto kFields = MakeFieldList();
32};
33
34template<> struct DescriptorForType<GetInfoResponse> {
35  static constexpr auto kFields =
36      MakeFieldList(MakeField(1, &GetInfoResponse::total_size),
37                    MakeField(2, &GetInfoResponse::available_size),
38                    MakeField(3, &GetInfoResponse::max_spaces),
39                    MakeField(4, &GetInfoResponse::space_list),
40                    MakeField(5, &GetInfoResponse::max_space_size),
41                    MakeField(6, &GetInfoResponse::wipe_disabled));
42};
43
44template<> struct DescriptorForType<CreateSpaceRequest> {
45  static constexpr auto kFields =
46      MakeFieldList(MakeField(1, &CreateSpaceRequest::index),
47                    MakeField(2, &CreateSpaceRequest::size),
48                    MakeField(3, &CreateSpaceRequest::controls),
49                    MakeField(4, &CreateSpaceRequest::authorization_value));
50};
51
52template<> struct DescriptorForType<CreateSpaceResponse> {
53  static constexpr auto kFields = MakeFieldList();
54};
55
56template<> struct DescriptorForType<GetSpaceInfoRequest> {
57  static constexpr auto kFields =
58      MakeFieldList(MakeField(1, &GetSpaceInfoRequest::index));
59};
60
61template<> struct DescriptorForType<GetSpaceInfoResponse> {
62  static constexpr auto kFields =
63      MakeFieldList(MakeField(1, &GetSpaceInfoResponse::size),
64                    MakeField(2, &GetSpaceInfoResponse::controls),
65                    MakeField(3, &GetSpaceInfoResponse::read_locked),
66                    MakeField(4, &GetSpaceInfoResponse::write_locked));
67};
68
69template<> struct DescriptorForType<DeleteSpaceRequest> {
70  static constexpr auto kFields =
71      MakeFieldList(MakeField(1, &DeleteSpaceRequest::index),
72                    MakeField(2, &DeleteSpaceRequest::authorization_value));
73};
74
75template<> struct DescriptorForType<DeleteSpaceResponse> {
76  static constexpr auto kFields = MakeFieldList();
77};
78
79template<> struct DescriptorForType<DisableCreateRequest> {
80  static constexpr auto kFields = MakeFieldList();
81};
82
83template<> struct DescriptorForType<DisableCreateResponse> {
84  static constexpr auto kFields = MakeFieldList();
85};
86
87template<> struct DescriptorForType<WriteSpaceRequest> {
88  static constexpr auto kFields =
89      MakeFieldList(MakeField(1, &WriteSpaceRequest::index),
90                    MakeField(2, &WriteSpaceRequest::buffer),
91                    MakeField(3, &WriteSpaceRequest::authorization_value));
92};
93
94template<> struct DescriptorForType<WriteSpaceResponse> {
95  static constexpr auto kFields = MakeFieldList();
96};
97
98template<> struct DescriptorForType<ReadSpaceRequest> {
99  static constexpr auto kFields =
100      MakeFieldList(MakeField(1, &ReadSpaceRequest::index),
101                    MakeField(2, &ReadSpaceRequest::authorization_value));
102};
103
104template<> struct DescriptorForType<ReadSpaceResponse> {
105  static constexpr auto kFields =
106      MakeFieldList(MakeField(1, &ReadSpaceResponse::buffer));
107};
108
109template<> struct DescriptorForType<LockSpaceWriteRequest> {
110  static constexpr auto kFields =
111      MakeFieldList(MakeField(1, &LockSpaceWriteRequest::index),
112                    MakeField(2, &LockSpaceWriteRequest::authorization_value));
113};
114
115template<> struct DescriptorForType<LockSpaceWriteResponse> {
116  static constexpr auto kFields = MakeFieldList();
117};
118
119template<> struct DescriptorForType<LockSpaceReadRequest> {
120  static constexpr auto kFields =
121      MakeFieldList(MakeField(1, &LockSpaceReadRequest::index),
122                    MakeField(2, &LockSpaceReadRequest::authorization_value));
123};
124
125template<> struct DescriptorForType<LockSpaceReadResponse> {
126  static constexpr auto kFields = MakeFieldList();
127};
128
129template<> struct DescriptorForType<WipeStorageRequest> {
130  static constexpr auto kFields = MakeFieldList();
131};
132
133template<> struct DescriptorForType<WipeStorageResponse> {
134  static constexpr auto kFields = MakeFieldList();
135};
136
137template<> struct DescriptorForType<DisableWipeRequest> {
138  static constexpr auto kFields = MakeFieldList();
139};
140
141template<> struct DescriptorForType<DisableWipeResponse> {
142  static constexpr auto kFields = MakeFieldList();
143};
144
145template<> struct DescriptorForType<Request> {
146  static constexpr auto kFields = MakeFieldList(
147      MakeOneOfField(1, &Request::payload, COMMAND_GET_INFO),
148      MakeOneOfField(2, &Request::payload, COMMAND_CREATE_SPACE),
149      MakeOneOfField(3, &Request::payload, COMMAND_GET_SPACE_INFO),
150      MakeOneOfField(4, &Request::payload, COMMAND_DELETE_SPACE),
151      MakeOneOfField(5, &Request::payload, COMMAND_DISABLE_CREATE),
152      MakeOneOfField(6, &Request::payload, COMMAND_WRITE_SPACE),
153      MakeOneOfField(7, &Request::payload, COMMAND_READ_SPACE),
154      MakeOneOfField(8, &Request::payload, COMMAND_LOCK_SPACE_WRITE),
155      MakeOneOfField(9, &Request::payload, COMMAND_LOCK_SPACE_READ),
156      MakeOneOfField(10, &Request::payload, COMMAND_WIPE_STORAGE),
157      MakeOneOfField(11, &Request::payload, COMMAND_DISABLE_WIPE));
158};
159
160template<> struct DescriptorForType<Response> {
161  static constexpr auto kFields = MakeFieldList(
162      MakeField(1, &Response::result),
163      MakeOneOfField(2, &Response::payload, COMMAND_GET_INFO),
164      MakeOneOfField(3, &Response::payload, COMMAND_CREATE_SPACE),
165      MakeOneOfField(4, &Response::payload, COMMAND_GET_SPACE_INFO),
166      MakeOneOfField(5, &Response::payload, COMMAND_DELETE_SPACE),
167      MakeOneOfField(6, &Response::payload, COMMAND_DISABLE_CREATE),
168      MakeOneOfField(7, &Response::payload, COMMAND_WRITE_SPACE),
169      MakeOneOfField(8, &Response::payload, COMMAND_READ_SPACE),
170      MakeOneOfField(9, &Response::payload, COMMAND_LOCK_SPACE_WRITE),
171      MakeOneOfField(10, &Response::payload, COMMAND_LOCK_SPACE_READ),
172      MakeOneOfField(11, &Response::payload, COMMAND_WIPE_STORAGE),
173      MakeOneOfField(12, &Response::payload, COMMAND_DISABLE_WIPE));
174};
175
176template <typename Message>
177bool Encode(const Message& msg, Blob* blob) {
178  BlobOutputStreamBuffer stream(blob);
179  return nvram::proto::Encode(msg, &stream) && stream.Truncate();
180}
181
182template <typename Message>
183bool Encode(const Message& msg, void* buffer, size_t* size) {
184  ArrayOutputStreamBuffer stream(buffer, *size);
185  if (!nvram::proto::Encode(msg, &stream)) {
186    return false;
187  }
188  *size = stream.bytes_written();
189  return true;
190}
191
192template <typename Message>
193bool Decode(const uint8_t* data, size_t size, Message* msg) {
194  InputStreamBuffer stream(data, size);
195  return nvram::proto::Decode(msg, &stream) && stream.Done();
196}
197
198// Instantiate the templates for the |Request| and |Response| message types.
199template NVRAM_EXPORT bool Encode<Request>(const Request&, Blob*);
200template NVRAM_EXPORT bool Encode<Request>(const Request&, void*, size_t*);
201template NVRAM_EXPORT bool Decode<Request>(const uint8_t*, size_t, Request*);
202
203template NVRAM_EXPORT bool Encode<Response>(const Response&, Blob*);
204template NVRAM_EXPORT bool Encode<Response>(const Response&, void*, size_t*);
205template NVRAM_EXPORT bool Decode<Response>(const uint8_t*, size_t, Response*);
206
207}  // namespace nvram
208