1 /*
2 * Copyright (c) 2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/ipc/ipc_service.h>
9 #include <zephyr/logging/log_link.h>
10 #include <zephyr/logging/log_multidomain_helper.h>
11 #include <zephyr/logging/log_core.h>
12 #include <zephyr/logging/log.h>
13
14 LOG_MODULE_REGISTER(link_ipc);
15
16 struct log_link_ipc_service {
17 struct ipc_ept ept;
18 struct log_multidomain_link link_remote;
19 };
20
bound_cb(void * priv)21 static void bound_cb(void *priv)
22 {
23 struct log_multidomain_link *link_remote = priv;
24
25 log_multidomain_link_on_started(link_remote, 0);
26 }
27
error_cb(const char * message,void * priv)28 static void error_cb(const char *message, void *priv)
29 {
30 struct log_multidomain_link *link_remote = priv;
31
32 log_multidomain_link_on_error(link_remote, -EIO);
33 }
34
recv_cb(const void * data,size_t len,void * priv)35 static void recv_cb(const void *data, size_t len, void *priv)
36 {
37 struct log_multidomain_link *link_remote = priv;
38
39 log_multidomain_link_on_recv_cb(link_remote, data, len);
40 }
41
link_ipc_service_send(struct log_multidomain_link * link_remote,void * data,size_t len)42 static int link_ipc_service_send(struct log_multidomain_link *link_remote,
43 void *data, size_t len)
44 {
45 struct log_link_ipc_service *link_ipc_service =
46 CONTAINER_OF(link_remote, struct log_link_ipc_service, link_remote);
47
48 return ipc_service_send(&link_ipc_service->ept, data, len);
49 }
50
link_ipc_service_init(struct log_multidomain_link * link_remote)51 static int link_ipc_service_init(struct log_multidomain_link *link_remote)
52 {
53 struct log_link_ipc_service *link_ipc_service =
54 CONTAINER_OF(link_remote, struct log_link_ipc_service, link_remote);
55 static struct ipc_ept_cfg ept_cfg = {
56 .name = "logging",
57 .prio = 0,
58 .cb = {
59 .bound = bound_cb,
60 .received = recv_cb,
61 .error = error_cb,
62 },
63 };
64 const struct device *ipc_instance = DEVICE_DT_GET(DT_CHOSEN(zephyr_log_ipc));
65 int err;
66
67 ept_cfg.priv = (void *)link_remote;
68 err = ipc_service_open_instance(ipc_instance);
69 if (err < 0 && err != -EALREADY) {
70 __ASSERT(0, "ipc_service_open_instance() failure (err:%d)\n", err);
71 return err;
72 }
73
74 err = ipc_service_register_endpoint(ipc_instance, &link_ipc_service->ept, &ept_cfg);
75
76 return err;
77 }
78
79 struct log_multidomain_link_transport_api log_link_ipc_service_transport_api = {
80 .init = link_ipc_service_init,
81 .send = link_ipc_service_send
82 };
83
84 static struct log_link_ipc_service link_ipc_service_data = {
85 .link_remote = {
86 .transport_api = &log_link_ipc_service_transport_api
87 }
88 };
89
90 LOG_LINK_DEF(link_ipc_service, log_multidomain_link_api,
91 CONFIG_LOG_LINK_IPC_SERVICE_BUFFER_SIZE,
92 &link_ipc_service_data.link_remote);
93
log_link_ipc_get_link(void)94 const struct log_link *log_link_ipc_get_link(void)
95 {
96 return &link_ipc_service;
97 }
98