blob: 0f1e471f77c09da2ecbf435f9f84998c3e4077f3 [file] [log] [blame]
Imre Kis6fd73d82024-07-04 13:36:10 +02001/*
2 * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include "fwu_provider_shim.h"
8
9#include "protocols/service/fwu/packed-c/fwu_proto.h"
10#include "util.h"
11
12static rpc_status_t receive(void *context, struct rpc_request *req)
13{
14 struct rpc_service_interface *fwu_rpc_interface = (struct rpc_service_interface *)context;
15 struct ts_fwu_request_header *req_header = NULL;
16 struct ts_fwu_response_header *resp_header = NULL;
17 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
18 struct rpc_request fwu_req = { 0 };
19
20 if (req->request.data_length < sizeof(*req_header))
21 return RPC_ERROR_INVALID_REQUEST_BODY;
22
23 if (req->response.size < sizeof(*resp_header))
24 return RPC_ERROR_INVALID_RESPONSE_BODY;
25
26 req_header = (struct ts_fwu_request_header *)req->request.data;
27 resp_header = (struct ts_fwu_response_header *)req->response.data;
28
29 /* Build new RPC request without the request headers */
30 fwu_req = *req;
31 fwu_req.opcode = req_header->func_id & 0xffff;
32 fwu_req.request.data = req_header->payload;
33 fwu_req.request.data_length -= sizeof(*req_header);
34 fwu_req.request.size -= sizeof(*req_header);
35 fwu_req.response.data = resp_header->payload;
36 fwu_req.response.size -= sizeof(*resp_header);
37
38 rpc_status = rpc_service_receive(fwu_rpc_interface, &fwu_req);
39 if (rpc_status != RPC_SUCCESS)
40 return rpc_status;
41
42 /* Insert service status into response buffer */
43 resp_header->status = fwu_req.service_status;
44
45 req->service_status = fwu_req.service_status;
46
47 /* Update response data length */
48 if (ADD_OVERFLOW(fwu_req.response.data_length, sizeof(uint32_t),
49 &req->response.data_length))
50 return RPC_ERROR_INVALID_RESPONSE_BODY;
51
52 if (req->response.data_length > req->response.size)
53 return RPC_ERROR_INVALID_RESPONSE_BODY;
54
55 return rpc_status;
56}
57
58struct rpc_service_interface *
59fwu_provider_shim_init(struct fwu_provider_shim *shim,
60 struct rpc_service_interface *fwu_rpc_interface)
61{
62 shim->shim_rpc_interface.receive = receive;
63 shim->shim_rpc_interface.context = fwu_rpc_interface;
64 shim->shim_rpc_interface.uuid = fwu_rpc_interface->uuid;
65
66 return &shim->shim_rpc_interface;
67}
68
69void fwu_provider_shim_deinit(struct fwu_provider_shim *shim)
70{
71 (void)shim;
72}