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_multidomain_helper.h>
10 #include <zephyr/logging/log_backend.h>
11 #include <zephyr/logging/log_ctrl.h>
12 
13 struct log_backend_ipc_service {
14 	struct ipc_ept ept;
15 	struct log_multidomain_backend backend_remote;
16 };
17 
bound_cb(void * priv)18 static void bound_cb(void *priv)
19 {
20 	struct log_multidomain_backend *backend_remote = priv;
21 
22 	log_multidomain_backend_on_started(backend_remote, 0);
23 }
24 
error_cb(const char * message,void * priv)25 static void error_cb(const char *message, void *priv)
26 {
27 	struct log_multidomain_backend *backend_remote = priv;
28 
29 	log_multidomain_backend_on_error(backend_remote, -EIO);
30 }
31 
recv_cb(const void * data,size_t len,void * priv)32 static void recv_cb(const void *data, size_t len, void *priv)
33 {
34 	struct log_multidomain_backend *backend_remote = priv;
35 
36 	log_multidomain_backend_on_recv_cb(backend_remote, data, len);
37 }
38 
backend_ipc_service_send(struct log_multidomain_backend * backend_remote,void * data,size_t len)39 static int backend_ipc_service_send(struct log_multidomain_backend *backend_remote,
40 				 void *data, size_t len)
41 {
42 	struct log_backend_ipc_service *backend_ipc_service =
43 		CONTAINER_OF(backend_remote, struct log_backend_ipc_service, backend_remote);
44 	int err = ipc_service_send(&backend_ipc_service->ept, data, len);
45 
46 	return err;
47 }
48 
backend_ipc_service_init(struct log_multidomain_backend * backend_remote)49 static int backend_ipc_service_init(struct log_multidomain_backend *backend_remote)
50 {
51 	struct log_backend_ipc_service *backend_ipc_service =
52 		CONTAINER_OF(backend_remote, struct log_backend_ipc_service, backend_remote);
53 	static struct ipc_ept_cfg ept_cfg = {
54 		.name = "logging",
55 		.prio = 0,
56 		.cb = {
57 			.bound    = bound_cb,
58 			.received = recv_cb,
59 			.error    = error_cb,
60 		},
61 	};
62 	const struct device *ipc_instance = DEVICE_DT_GET(DT_CHOSEN(zephyr_log_ipc));
63 	int err;
64 
65 	ept_cfg.priv = (void *)backend_remote;
66 	err = ipc_service_open_instance(ipc_instance);
67 	if (err < 0 && err != -EALREADY) {
68 		return err;
69 	}
70 
71 	err = ipc_service_register_endpoint(ipc_instance, &backend_ipc_service->ept, &ept_cfg);
72 
73 	return err;
74 }
75 
76 struct log_multidomain_backend_transport_api log_backend_ipc_service_transport_api = {
77 	.init = backend_ipc_service_init,
78 	.send = backend_ipc_service_send
79 };
80 
81 static struct log_backend_ipc_service backend_ipc_service_data = {
82 	.backend_remote = {
83 		.transport_api = &log_backend_ipc_service_transport_api
84 	}
85 };
86 
87 LOG_BACKEND_DEFINE(backend_ipc_service,
88 		   log_multidomain_backend_api,
89 		   true,
90 		   &backend_ipc_service_data.backend_remote);
91