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