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