247 lines
6.9 KiB
C
247 lines
6.9 KiB
C
/*
|
|
* Copyright (c) 2021 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/kernel.h>
|
|
#include <zephyr/ipc/ipc_service.h>
|
|
#include <zephyr/logging/log_multidomain_helper.h>
|
|
#include <zephyr/logging/log_core.h>
|
|
#include <zephyr/logging/log_backend.h>
|
|
#include <zephyr/logging/log_ctrl.h>
|
|
|
|
static void process(const struct log_backend *const backend,
|
|
union log_msg_generic *msg)
|
|
{
|
|
int err;
|
|
struct log_multidomain_backend *backend_remote = backend->cb->ctx;
|
|
uint32_t dlen = msg->log.hdr.desc.data_len;
|
|
int fsc_plen;
|
|
|
|
if (backend_remote->panic) {
|
|
return;
|
|
}
|
|
|
|
fsc_plen = cbprintf_fsc_package(msg->log.data,
|
|
msg->log.hdr.desc.package_len,
|
|
NULL,
|
|
0);
|
|
if (fsc_plen < 0) {
|
|
__ASSERT_NO_MSG(false);
|
|
return;
|
|
}
|
|
|
|
/* Need to ensure that package is aligned to a pointer size. */
|
|
uint32_t msg_len = Z_LOG_MSG2_LEN(fsc_plen, dlen);
|
|
uint8_t buf[msg_len + sizeof(void *)] __aligned(sizeof(void *));
|
|
size_t msg_offset = offsetof(struct log_multidomain_msg, data);
|
|
struct log_multidomain_msg *out_msg =
|
|
(struct log_multidomain_msg *)&buf[sizeof(void *) - msg_offset];
|
|
struct log_msg *out_log_msg = (struct log_msg *)out_msg->data.log_msg.data;
|
|
|
|
/* Set ipc message id. */
|
|
out_msg->id = Z_LOG_MULTIDOMAIN_ID_MSG;
|
|
out_msg->status = Z_LOG_MULTIDOMAIN_STATUS_OK;
|
|
/* Copy log message header. */
|
|
memcpy(&out_log_msg->hdr, &msg->log.hdr, sizeof(struct log_msg_hdr));
|
|
/* Update package len field in the message descriptor. */
|
|
out_log_msg->hdr.desc.package_len = fsc_plen;
|
|
|
|
out_log_msg->hdr.source = out_log_msg->hdr.source ?
|
|
(const void *)(IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ?
|
|
log_dynamic_source_id((void *)out_log_msg->hdr.source) :
|
|
log_const_source_id((void *)out_log_msg->hdr.source)) :
|
|
(const void *)-1;
|
|
|
|
/* Fill new package. */
|
|
fsc_plen = cbprintf_fsc_package(msg->log.data, msg->log.hdr.desc.package_len,
|
|
out_log_msg->data, fsc_plen);
|
|
if (fsc_plen < 0) {
|
|
__ASSERT_NO_MSG(false);
|
|
return;
|
|
}
|
|
|
|
/* Copy data */
|
|
if (dlen) {
|
|
memcpy(&out_log_msg->data[fsc_plen],
|
|
&msg->log.data[msg->log.hdr.desc.package_len],
|
|
dlen);
|
|
}
|
|
|
|
err = backend_remote->transport_api->send(backend_remote, out_msg, msg_len + msg_offset);
|
|
if (err < 0) {
|
|
__ASSERT(false, "Unexpected error: %d\n", err);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void log_multidomain_backend_on_started(struct log_multidomain_backend *backend_remote, int err)
|
|
{
|
|
backend_remote->status = err;
|
|
|
|
k_sem_give(&backend_remote->rdy_sem);
|
|
}
|
|
|
|
void log_multidomain_backend_on_error(struct log_multidomain_backend *backend_remote, int err)
|
|
{
|
|
backend_remote->status = err;
|
|
}
|
|
|
|
static void get_name_response(struct log_multidomain_backend *backend_remote,
|
|
uint8_t domain_id, uint16_t source_id,
|
|
bool domain_name)
|
|
{
|
|
const char *name = domain_name ?
|
|
log_domain_name_get(domain_id) :
|
|
log_source_name_get(domain_id, source_id);
|
|
size_t slen = strlen(name);
|
|
size_t msg_offset = offsetof(struct log_multidomain_msg, data);
|
|
size_t msg_size = slen + 1 + msg_offset +
|
|
(domain_name ? sizeof(struct log_multidomain_domain_name) :
|
|
sizeof(struct log_multidomain_source_name));
|
|
uint8_t msg_buf[msg_size];
|
|
struct log_multidomain_msg *outmsg = (struct log_multidomain_msg *)msg_buf;
|
|
char *dst = domain_name ?
|
|
outmsg->data.domain_name.name :
|
|
outmsg->data.source_name.name;
|
|
int err;
|
|
|
|
outmsg->id = domain_name ? Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_NAME :
|
|
Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_NAME;
|
|
outmsg->status = Z_LOG_MULTIDOMAIN_STATUS_OK;
|
|
memcpy(dst, name, slen);
|
|
dst[slen] = '\0';
|
|
|
|
if (domain_name) {
|
|
outmsg->data.domain_name.domain_id = domain_id;
|
|
} else {
|
|
outmsg->data.source_name.domain_id = domain_id;
|
|
outmsg->data.source_name.source_id = source_id;
|
|
}
|
|
|
|
err = backend_remote->transport_api->send(backend_remote, outmsg, msg_size);
|
|
__ASSERT_NO_MSG(err >= 0);
|
|
}
|
|
|
|
void log_multidomain_backend_on_recv_cb(struct log_multidomain_backend *backend_remote,
|
|
const void *data, size_t len)
|
|
{
|
|
struct log_multidomain_msg *msg = (struct log_multidomain_msg *)data;
|
|
struct log_multidomain_msg outmsg = {
|
|
.id = msg->id,
|
|
.status = Z_LOG_MULTIDOMAIN_STATUS_OK
|
|
};
|
|
int err;
|
|
|
|
memcpy(&outmsg, msg, sizeof(struct log_multidomain_msg));
|
|
|
|
switch (msg->id) {
|
|
case Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_CNT:
|
|
outmsg.data.domain_cnt.count = log_domains_count();
|
|
break;
|
|
|
|
case Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_CNT:
|
|
outmsg.data.source_cnt.count =
|
|
log_src_cnt_get(msg->data.source_cnt.domain_id);
|
|
break;
|
|
|
|
case Z_LOG_MULTIDOMAIN_ID_GET_DOMAIN_NAME:
|
|
get_name_response(backend_remote,
|
|
msg->data.domain_name.domain_id,
|
|
0, true);
|
|
return;
|
|
|
|
case Z_LOG_MULTIDOMAIN_ID_GET_SOURCE_NAME:
|
|
get_name_response(backend_remote,
|
|
msg->data.source_name.domain_id,
|
|
msg->data.source_name.source_id,
|
|
false);
|
|
return;
|
|
|
|
case Z_LOG_MULTIDOMAIN_ID_GET_LEVELS:
|
|
outmsg.data.levels.level =
|
|
log_filter_get(backend_remote->log_backend,
|
|
outmsg.data.levels.domain_id,
|
|
outmsg.data.levels.source_id,
|
|
false);
|
|
outmsg.data.levels.runtime_level =
|
|
log_filter_get(backend_remote->log_backend,
|
|
outmsg.data.levels.domain_id,
|
|
outmsg.data.levels.source_id,
|
|
true);
|
|
break;
|
|
case Z_LOG_MULTIDOMAIN_ID_SET_RUNTIME_LEVEL:
|
|
outmsg.data.set_rt_level.runtime_level =
|
|
log_filter_set(backend_remote->log_backend,
|
|
outmsg.data.set_rt_level.domain_id,
|
|
outmsg.data.set_rt_level.source_id,
|
|
outmsg.data.set_rt_level.runtime_level);
|
|
break;
|
|
case Z_LOG_MULTIDOMAIN_ID_READY:
|
|
backend_remote->ready = true;
|
|
break;
|
|
default:
|
|
__ASSERT(0, "Unexpected message");
|
|
break;
|
|
}
|
|
|
|
err = backend_remote->transport_api->send(backend_remote, &outmsg, sizeof(outmsg));
|
|
__ASSERT_NO_MSG(err >= 0);
|
|
}
|
|
|
|
static void init(struct log_backend const *const backend)
|
|
{
|
|
struct log_multidomain_backend *backend_remote = backend->cb->ctx;
|
|
int err;
|
|
|
|
backend_remote->log_backend = backend;
|
|
k_sem_init(&backend_remote->rdy_sem, 0, 1);
|
|
|
|
err = backend_remote->transport_api->init(backend_remote);
|
|
__ASSERT_NO_MSG(err >= 0);
|
|
|
|
err = k_sem_take(&backend_remote->rdy_sem, K_MSEC(4000));
|
|
__ASSERT_NO_MSG(err >= 0);
|
|
}
|
|
|
|
static int is_ready(struct log_backend const *const backend)
|
|
{
|
|
struct log_multidomain_backend *backend_remote = backend->cb->ctx;
|
|
|
|
return backend_remote->ready ? 0 : -EINPROGRESS;
|
|
}
|
|
|
|
static void panic(struct log_backend const *const backend)
|
|
{
|
|
struct log_multidomain_backend *backend_remote = backend->cb->ctx;
|
|
|
|
backend_remote->panic = true;
|
|
}
|
|
|
|
static void dropped(const struct log_backend *const backend, uint32_t cnt)
|
|
{
|
|
struct log_multidomain_backend *backend_remote = backend->cb->ctx;
|
|
int err;
|
|
struct log_multidomain_msg msg = {
|
|
.id = Z_LOG_MULTIDOMAIN_ID_DROPPED,
|
|
.status = Z_LOG_MULTIDOMAIN_STATUS_OK,
|
|
.data = {
|
|
.dropped = {
|
|
.dropped = cnt
|
|
}
|
|
}
|
|
};
|
|
|
|
err = backend_remote->transport_api->send(backend_remote, &msg, sizeof(msg));
|
|
__ASSERT_NO_MSG(err >= 0);
|
|
}
|
|
|
|
const struct log_backend_api log_multidomain_backend_api = {
|
|
.process = process,
|
|
.panic = panic,
|
|
.dropped = dropped,
|
|
.init = init,
|
|
.is_ready = is_ready
|
|
};
|