1 /*
2 * Copyright 2017-2023, NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include <assert.h>
10 #include <string.h>
11
12 #include "srtm_heap.h"
13 #include "srtm_dispatcher.h"
14 #include "srtm_dispatcher_struct.h"
15 #include "srtm_peercore.h"
16 #include "srtm_peercore_struct.h"
17 #include "srtm_channel.h"
18 #include "srtm_channel_struct.h"
19 #include "srtm_rpmsg_endpoint.h"
20 #include "rpmsg_ns.h"
21
22 /*******************************************************************************
23 * Definitions
24 ******************************************************************************/
25 #ifndef SRTM_DEBUG_COMMUNICATION
26 #define SRTM_DEBUG_COMMUNICATION (0)
27 #endif
28
29 typedef struct _srtm_rpmsg_endpoint
30 {
31 struct _srtm_channel channel;
32 srtm_rpmsg_endpoint_config_t config;
33 struct rpmsg_lite_endpoint *rpmsgEndpoint;
34 srtm_rpmsg_endpoint_rx_cb_t rxCallback;
35 void *rxCallbackParam;
36 bool started;
37 } *srtm_rpmsg_endpoint_t;
38
39 /*******************************************************************************
40 * Prototypes
41 ******************************************************************************/
42
43 /*******************************************************************************
44 * Variables
45 ******************************************************************************/
46
47 /*******************************************************************************
48 * Code
49 ******************************************************************************/
SRTM_RPMsgEndpoint_RxHandler(void * payload,uint32_t payload_len,uint32_t src,void * priv)50 static int32_t SRTM_RPMsgEndpoint_RxHandler(void *payload, uint32_t payload_len, uint32_t src, void *priv)
51 {
52 srtm_rpmsg_endpoint_t handle = (srtm_rpmsg_endpoint_t)(void *)priv;
53
54 assert(handle != NULL);
55
56 #if SRTM_DEBUG_COMMUNICATION
57 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_ERROR, "%s: RPMsg recv:\r\n\t", __func__);
58 for (uint32_t i = 0U; i < payload_len; i++)
59 {
60 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_ERROR, "%x ", ((uint8_t *)payload)[i]);
61 }
62 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_ERROR, "\r\n");
63 #endif
64
65 if (handle->config.peerAddr == RL_ADDR_ANY)
66 {
67 handle->config.peerAddr = src;
68 }
69
70 if (handle->started)
71 {
72 if (handle->rxCallback != NULL)
73 {
74 return handle->rxCallback(&handle->channel, payload, payload_len, src, handle->rxCallbackParam);
75 }
76
77 assert(handle->channel.core != NULL);
78 assert(handle->channel.core->dispatcher != NULL);
79
80 (void)SRTM_Dispatcher_PostRecvData(handle->channel.core->dispatcher, &handle->channel, payload, payload_len);
81 }
82 else
83 {
84 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_WARN, "%s: Get data before channel start\r\n", __func__);
85 }
86
87 return RL_RELEASE;
88 }
89
SRTM_RPMsgEndpoint_Start(srtm_channel_t channel)90 static srtm_status_t SRTM_RPMsgEndpoint_Start(srtm_channel_t channel)
91 {
92 srtm_rpmsg_endpoint_t handle = (srtm_rpmsg_endpoint_t)(void *)channel;
93 srtm_status_t status = SRTM_Status_Success;
94
95 assert(handle != NULL);
96
97 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
98
99 handle->started = true;
100
101 return status;
102 }
103
SRTM_RPMsgEndpoint_Stop(srtm_channel_t channel)104 static srtm_status_t SRTM_RPMsgEndpoint_Stop(srtm_channel_t channel)
105 {
106 srtm_rpmsg_endpoint_t handle = (srtm_rpmsg_endpoint_t)(void *)channel;
107 srtm_status_t status = SRTM_Status_Success;
108
109 assert(handle != NULL);
110
111 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
112
113 handle->started = false;
114
115 return status;
116 }
117
SRTM_RPMsgEndpoint_RpmsgLiteSendPre(srtm_channel_t channel,void * data,uint32_t len)118 static void SRTM_RPMsgEndpoint_RpmsgLiteSendPre(srtm_channel_t channel, void *data, uint32_t len)
119 {
120 if (channel->sendDataPreCallback != NULL)
121 {
122 channel->sendDataPreCallback(channel, data, len);
123 }
124 }
125
SRTM_RPMsgEndpoint_RpmsgLiteSendPost(srtm_channel_t channel,void * data,uint32_t len)126 static void SRTM_RPMsgEndpoint_RpmsgLiteSendPost(srtm_channel_t channel, void *data, uint32_t len)
127 {
128 if (channel->sendDataPostCallback != NULL)
129 {
130 channel->sendDataPostCallback(channel, data, len);
131 }
132 }
133
SRTM_RPMsgEndpoint_SendData(srtm_channel_t channel,void * data,uint32_t len)134 static srtm_status_t SRTM_RPMsgEndpoint_SendData(srtm_channel_t channel, void *data, uint32_t len)
135 {
136 srtm_rpmsg_endpoint_t handle = (srtm_rpmsg_endpoint_t)(void *)channel;
137 srtm_status_t status = SRTM_Status_InvalidState;
138
139 assert(handle != NULL);
140 assert(handle->config.rpmsgHandle != NULL);
141 assert(handle->rpmsgEndpoint != NULL);
142
143 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_DEBUG, "%s: len %d\r\n", __func__, len);
144
145 if (handle->started)
146 {
147 #if SRTM_DEBUG_COMMUNICATION
148 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_ERROR, "%s: RPMsg send:\r\n\t", __func__);
149 for (uint32_t i = 0U; i < len; i++)
150 {
151 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_ERROR, "%x ", ((uint8_t *)data)[i]);
152 }
153 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_ERROR, "\r\n");
154 #endif
155 SRTM_RPMsgEndpoint_RpmsgLiteSendPre(channel, data, len);
156 if (rpmsg_lite_send(handle->config.rpmsgHandle, handle->rpmsgEndpoint, handle->config.peerAddr, (char *)data,
157 len, RL_BLOCK) == RL_SUCCESS)
158 {
159 status = SRTM_Status_Success;
160 }
161 else
162 {
163 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_ERROR, "%s: RPMsg send failed\r\n", __func__);
164 status = SRTM_Status_TransferFailed;
165 }
166 SRTM_RPMsgEndpoint_RpmsgLiteSendPost(channel, data, len);
167 }
168 else
169 {
170 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_WARN, "%s: channel not started\r\n", __func__);
171 }
172
173 return status;
174 }
175
SRTM_RPMsgEndpoint_Create(srtm_rpmsg_endpoint_config_t * config)176 srtm_channel_t SRTM_RPMsgEndpoint_Create(srtm_rpmsg_endpoint_config_t *config)
177 {
178 srtm_rpmsg_endpoint_t handle;
179
180 assert(config != NULL);
181 assert(config->rpmsgHandle != NULL);
182
183 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
184
185 handle = (srtm_rpmsg_endpoint_t)SRTM_Heap_Malloc(sizeof(struct _srtm_rpmsg_endpoint));
186 assert(handle != NULL);
187
188 handle->started = false;
189 handle->rxCallback = NULL;
190 handle->rxCallbackParam = NULL;
191 #if defined(SRTM_STATIC_API) && SRTM_STATIC_API
192 handle->rpmsgEndpoint =
193 rpmsg_lite_create_ept(config->rpmsgHandle, config->localAddr, SRTM_RPMsgEndpoint_RxHandler, handle, config->ept_context);
194 #else
195 handle->rpmsgEndpoint =
196 rpmsg_lite_create_ept(config->rpmsgHandle, config->localAddr, SRTM_RPMsgEndpoint_RxHandler, handle);
197 #endif
198 assert(handle->rpmsgEndpoint != NULL);
199
200 (void)memcpy(&handle->config, config, sizeof(struct _srtm_rpmsg_endpoint_config));
201 if (config->localAddr == RL_ADDR_ANY)
202 {
203 handle->config.localAddr = handle->rpmsgEndpoint->addr;
204 }
205
206 SRTM_List_Init(&handle->channel.node);
207 handle->channel.core = NULL;
208 handle->channel.destroy = SRTM_RPMsgEndpoint_Destroy;
209 handle->channel.start = SRTM_RPMsgEndpoint_Start;
210 handle->channel.stop = SRTM_RPMsgEndpoint_Stop;
211 handle->channel.sendData = SRTM_RPMsgEndpoint_SendData;
212 handle->channel.sendDataPreCallback = NULL;
213 handle->channel.sendDataPostCallback = NULL;
214
215 if (config->epName != NULL)
216 {
217 if (rpmsg_ns_announce(config->rpmsgHandle, handle->rpmsgEndpoint, config->epName, (uint32_t)RL_NS_CREATE) !=
218 RL_SUCCESS)
219 {
220 assert((bool)false);
221 }
222 }
223
224 return &handle->channel;
225 }
226
SRTM_RPMsgEndpoint_Destroy(srtm_channel_t channel)227 void SRTM_RPMsgEndpoint_Destroy(srtm_channel_t channel)
228 {
229 srtm_rpmsg_endpoint_t handle = (srtm_rpmsg_endpoint_t)(void *)channel;
230
231 assert(channel != NULL);
232 assert(channel->core == NULL); /* Channel must be removed from core before destroy */
233 assert(SRTM_List_IsEmpty(&channel->node)); /* Channel must not on any list */
234
235 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
236
237 (void)rpmsg_lite_destroy_ept(handle->config.rpmsgHandle, handle->rpmsgEndpoint);
238
239 SRTM_Heap_Free(handle);
240 }
241
SRTM_RPMsgEndpoint_OverrideRxHandler(srtm_channel_t channel,srtm_rpmsg_endpoint_rx_cb_t callback,void * param)242 srtm_status_t SRTM_RPMsgEndpoint_OverrideRxHandler(srtm_channel_t channel,
243 srtm_rpmsg_endpoint_rx_cb_t callback,
244 void *param)
245 {
246 srtm_rpmsg_endpoint_t handle = (srtm_rpmsg_endpoint_t)(void *)channel;
247
248 assert(handle != NULL);
249
250 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
251
252 handle->rxCallback = callback;
253 handle->rxCallbackParam = param;
254
255 return SRTM_Status_Success;
256 }
257