Gabor Ambrus | 7ccab79 | 2023-08-14 22:56:56 +0200 | [diff] [blame] | 1 | // 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 | */ |
| 23 | static 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 | */ |
| 45 | log_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 | */ |
| 98 | struct 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 | } |