blob: 21a52bf2b4dc0133cd998d513b858079c5ed4673 [file] [log] [blame]
Gabor Ambrus7ccab792023-08-14 22:56:56 +02001// SPDX-License-Identifier: BSD-3-Clause
2/*
3 * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
4 */
5
6#include "log_client.h"
7
8#include <string.h>
9
10#include "components/service/log/factory/log_factory.h"
11#include "protocols/rpc/common/packed-c/status.h"
12#include "protocols/service/log/packed-c/log_proto.h"
13#include "rpc_caller_session.h"
14#include "util.h"
15#include "trace.h"
16#include "ffa_api.h"
17
18/*
19 * Custom logging function, which sends the log message to
20 * the logging backend, but can fall back to the default
21 * logging interface of the system.
22 */
23static void log_client_trace_puts(const char *str)
24{
25 struct log_backend *log_backend;
26 log_status_t log_status = LOG_STATUS_GENERIC_ERROR;
27
28 /* log message using logging sp */
29 log_backend = log_factory_get_backend_instance();
30
31 /* in case logging to sp fails we still want to log it with FFA */
32 if (log_backend) {
33 log_status = log_backend->interface->puts(log_backend->context, str);
34 if (log_status == LOG_STATUS_SUCCESS)
35 return;
36 }
37
38 /* log message using FFA CONSOLE LOG */
39 trace_puts(str);
40}
41
42/*
43 * Client function for sending string to Logging SP.
44 */
45log_status_t log_client_puts(void *context, const char *msg)
46{
47 struct log_client *log_client = (struct log_client *)context;
48 uint8_t *request = NULL;
49 uint8_t *response = NULL;
50 size_t request_length = 0;
51 size_t response_length = 0;
52 size_t msg_length = 0;
53 struct log_request *request_desc = NULL;
54 rpc_call_handle handle = 0;
55 rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
56 log_status_t log_status = LOG_STATUS_GENERIC_ERROR;
57
58 service_status_t service_status = LOG_STATUS_SUCCESS;
59
60 if (log_client->client.session == NULL)
61 return LOG_STATUS_GENERIC_ERROR;
62
63 /* Validating input parameters */
64 if (msg == NULL)
65 return LOG_STATUS_INVALID_PARAMETER;
66
67 msg_length = strlen(msg);
68
69 /* Add one for null termination */
70 if (ADD_OVERFLOW(msg_length, 1, &msg_length))
71 return LOG_STATUS_INVALID_PARAMETER;
72
73 if (ADD_OVERFLOW(sizeof(*request_desc), msg_length, &request_length))
74 return LOG_STATUS_INVALID_PARAMETER;
75
76 /* RPC call */
77 handle = rpc_caller_session_begin(log_client->client.session, &request, request_length, 0);
78 if (handle) {
79 request_desc = (struct log_request *)request;
80 memcpy(&request_desc->msg, msg, msg_length);
81 request_desc->msg_length = msg_length;
82
83 rpc_status = rpc_caller_session_invoke(handle, TS_LOG_OPCODE_PUTS, &response,
84 &response_length, &service_status);
85
86 if (rpc_status == PSA_SUCCESS)
87 log_status = service_status;
88
89 rpc_caller_session_end(handle);
90 }
91
92 return log_status;
93}
94
95/*
96 * Client initialization function.
97 */
98struct log_backend *log_client_init(struct log_client *context, struct rpc_caller_session *session)
99{
100 service_client_init(&context->client, session);
101
102 static const struct log_backend_interface interface = { log_client_puts };
103
104 context->backend.context = context;
105 context->backend.interface = &interface;
106
107 trace_puts_interface = &log_client_trace_puts;
108
109 return &context->backend;
110}