1 /*
2 * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 #include <string.h>
7 #include "common/tlv/tlv.h"
8 #include "common/endian/le.h"
9 #include "protocols/rpc/common/packed-c/status.h"
10 #include "protocols/service/block_storage/packed-c/messages.h"
11 #include "packedc_block_storage_serializer.h"
12
13
14 /* Operation: get_partition_info */
deserialize_get_partition_info_req(const struct rpc_buffer * req_buf,struct uuid_octets * partition_guid)15 rpc_status_t deserialize_get_partition_info_req(const struct rpc_buffer *req_buf,
16 struct uuid_octets *partition_guid)
17 {
18 rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
19 struct ts_block_storage_get_partition_info_in recv_msg;
20 size_t expected_fixed_len = sizeof(struct ts_block_storage_get_partition_info_in);
21
22 if (expected_fixed_len <= req_buf->data_length) {
23
24 memcpy(&recv_msg, req_buf->data, expected_fixed_len);
25 memcpy(&partition_guid->octets, recv_msg.partition_guid, sizeof(partition_guid->octets));
26 rpc_status = RPC_SUCCESS;
27 }
28
29 return rpc_status;
30 }
31
serialize_get_partition_info_resp(struct rpc_buffer * resp_buf,struct storage_partition_info * info)32 rpc_status_t serialize_get_partition_info_resp(struct rpc_buffer *resp_buf,
33 struct storage_partition_info *info)
34 {
35 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
36 struct ts_block_storage_get_partition_info_out resp_msg;
37 size_t fixed_len = sizeof(struct ts_block_storage_get_partition_info_out);
38
39 resp_msg.num_blocks = info->num_blocks;
40 resp_msg.block_size = info->block_size;
41
42 memcpy(resp_msg.partition_guid,
43 info->partition_guid.octets, TS_BLOCK_STORAGE_GUID_OCTET_LEN);
44
45 memcpy(resp_msg.parent_guid,
46 info->parent_guid.octets, TS_BLOCK_STORAGE_GUID_OCTET_LEN);
47
48 if (fixed_len <= resp_buf->size) {
49
50 memcpy(resp_buf->data, &resp_msg, fixed_len);
51 resp_buf->data_length = fixed_len;
52 rpc_status = RPC_SUCCESS;
53 }
54
55 return rpc_status;
56 }
57
58 /* Operation: open */
deserialize_open_req(const struct rpc_buffer * req_buf,struct uuid_octets * partition_guid)59 rpc_status_t deserialize_open_req(const struct rpc_buffer *req_buf,
60 struct uuid_octets *partition_guid)
61 {
62 rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
63 struct ts_block_storage_open_in recv_msg;
64 size_t expected_fixed_len = sizeof(struct ts_block_storage_open_in);
65
66 if (expected_fixed_len <= req_buf->data_length) {
67
68 memcpy(&recv_msg, req_buf->data, expected_fixed_len);
69 memcpy(&partition_guid->octets, recv_msg.partition_guid, sizeof(partition_guid->octets));
70 rpc_status = RPC_SUCCESS;
71 }
72
73 return rpc_status;
74 }
75
serialize_open_resp(struct rpc_buffer * resp_buf,storage_partition_handle_t handle)76 rpc_status_t serialize_open_resp(struct rpc_buffer *resp_buf,
77 storage_partition_handle_t handle)
78 {
79 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
80 struct ts_block_storage_open_out resp_msg;
81 size_t fixed_len = sizeof(struct ts_block_storage_open_out);
82
83 resp_msg.handle = handle;
84
85 if (fixed_len <= resp_buf->size) {
86
87 memcpy(resp_buf->data, &resp_msg, fixed_len);
88 resp_buf->data_length = fixed_len;
89 rpc_status = RPC_SUCCESS;
90 }
91
92 return rpc_status;
93 }
94
95 /* Operation: close */
deserialize_close_req(const struct rpc_buffer * req_buf,storage_partition_handle_t * handle)96 rpc_status_t deserialize_close_req(const struct rpc_buffer *req_buf,
97 storage_partition_handle_t *handle)
98 {
99 rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
100 struct ts_block_storage_close_in recv_msg;
101 size_t expected_fixed_len = sizeof(struct ts_block_storage_close_in);
102
103 if (expected_fixed_len <= req_buf->data_length) {
104
105 memcpy(&recv_msg, req_buf->data, expected_fixed_len);
106 *handle = recv_msg.handle;
107 rpc_status = RPC_SUCCESS;
108 }
109
110 return rpc_status;
111 }
112
113 /* Operation: read */
deserialize_read_req(const struct rpc_buffer * req_buf,storage_partition_handle_t * handle,uint64_t * lba,size_t * offset,size_t * len)114 rpc_status_t deserialize_read_req(const struct rpc_buffer *req_buf,
115 storage_partition_handle_t *handle,
116 uint64_t *lba,
117 size_t *offset,
118 size_t *len)
119 {
120 rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
121 struct ts_block_storage_read_in recv_msg;
122 size_t expected_fixed_len = sizeof(struct ts_block_storage_read_in);
123
124 if (expected_fixed_len <= req_buf->data_length) {
125
126 memcpy(&recv_msg, req_buf->data, expected_fixed_len);
127 *handle = recv_msg.handle;
128 *lba = recv_msg.lba;
129 *offset = recv_msg.offset;
130 *len = recv_msg.len;
131 rpc_status = RPC_SUCCESS;
132 }
133
134 return rpc_status;
135 }
136
137 /* Operation: write */
deserialize_write_req(const struct rpc_buffer * req_buf,storage_partition_handle_t * handle,uint64_t * lba,size_t * offset,const uint8_t ** data,size_t * data_length)138 rpc_status_t deserialize_write_req(const struct rpc_buffer *req_buf,
139 storage_partition_handle_t *handle,
140 uint64_t *lba,
141 size_t *offset,
142 const uint8_t **data,
143 size_t *data_length)
144 {
145 rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
146 struct ts_block_storage_write_in recv_msg;
147 size_t expected_fixed_len = sizeof(struct ts_block_storage_write_in);
148
149 if (expected_fixed_len <= req_buf->data_length) {
150
151 memcpy(&recv_msg, req_buf->data, expected_fixed_len);
152
153 *handle = recv_msg.handle;
154 *lba = recv_msg.lba;
155 *offset = recv_msg.offset;
156
157 *data = (const uint8_t*)req_buf->data + expected_fixed_len;
158 *data_length = req_buf->data_length - expected_fixed_len;
159
160 rpc_status = RPC_SUCCESS;
161 }
162
163 return rpc_status;
164 }
165
serialize_write_resp(struct rpc_buffer * resp_buf,size_t num_written)166 rpc_status_t serialize_write_resp(struct rpc_buffer *resp_buf,
167 size_t num_written)
168 {
169 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
170 struct ts_block_storage_write_out resp_msg;
171 size_t fixed_len = sizeof(struct ts_block_storage_write_out);
172
173 resp_msg.num_written = num_written;
174
175 if (fixed_len <= resp_buf->size) {
176
177 memcpy(resp_buf->data, &resp_msg, fixed_len);
178 resp_buf->data_length = fixed_len;
179 rpc_status = RPC_SUCCESS;
180 }
181
182 return rpc_status;
183 }
184
185 /* Operation: erase */
deserialize_erase_req(const struct rpc_buffer * req_buf,storage_partition_handle_t * handle,uint64_t * begin_lba,size_t * num_blocks)186 rpc_status_t deserialize_erase_req(const struct rpc_buffer *req_buf,
187 storage_partition_handle_t *handle,
188 uint64_t *begin_lba,
189 size_t *num_blocks)
190 {
191 rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
192 struct ts_block_storage_erase_in recv_msg;
193 size_t expected_fixed_len = sizeof(struct ts_block_storage_erase_in);
194
195 if (expected_fixed_len <= req_buf->data_length) {
196
197 memcpy(&recv_msg, req_buf->data, expected_fixed_len);
198
199 *handle = recv_msg.handle;
200 *begin_lba = recv_msg.begin_lba;
201 *num_blocks = (size_t)recv_msg.num_blocks;
202
203 rpc_status = RPC_SUCCESS;
204 }
205
206 return rpc_status;
207 }
208
209 /* Singleton method to provide access to the serializer instance */
packedc_block_storage_serializer_instance(void)210 const struct block_storage_serializer *packedc_block_storage_serializer_instance(void)
211 {
212 static const struct block_storage_serializer instance =
213 {
214 deserialize_get_partition_info_req,
215 serialize_get_partition_info_resp,
216 deserialize_open_req,
217 serialize_open_resp,
218 deserialize_close_req,
219 deserialize_read_req,
220 deserialize_write_req,
221 serialize_write_resp,
222 deserialize_erase_req
223 };
224
225 return &instance;
226 }
227