1 /*
2 * Copyright 2017-2021, 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_SendData(srtm_channel_t channel,void * data,uint32_t len)118 static srtm_status_t SRTM_RPMsgEndpoint_SendData(srtm_channel_t channel, void *data, uint32_t len)
119 {
120 srtm_rpmsg_endpoint_t handle = (srtm_rpmsg_endpoint_t)(void *)channel;
121 srtm_status_t status = SRTM_Status_InvalidState;
122
123 assert(handle != NULL);
124 assert(handle->config.rpmsgHandle != NULL);
125 assert(handle->rpmsgEndpoint != NULL);
126
127 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_DEBUG, "%s: len %d\r\n", __func__, len);
128
129 if (handle->started)
130 {
131 #if SRTM_DEBUG_COMMUNICATION
132 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_ERROR, "%s: RPMsg send:\r\n\t", __func__);
133 for (uint32_t i = 0U; i < len; i++)
134 {
135 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_ERROR, "%x ", ((uint8_t *)data)[i]);
136 }
137 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_ERROR, "\r\n");
138 #endif
139 if (rpmsg_lite_send(handle->config.rpmsgHandle, handle->rpmsgEndpoint, handle->config.peerAddr, (char *)data,
140 len, RL_BLOCK) == RL_SUCCESS)
141 {
142 status = SRTM_Status_Success;
143 }
144 else
145 {
146 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_ERROR, "%s: RPMsg send failed\r\n", __func__);
147 status = SRTM_Status_TransferFailed;
148 }
149 }
150 else
151 {
152 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_WARN, "%s: channel not started\r\n", __func__);
153 }
154
155 return status;
156 }
157
SRTM_RPMsgEndpoint_Create(srtm_rpmsg_endpoint_config_t * config)158 srtm_channel_t SRTM_RPMsgEndpoint_Create(srtm_rpmsg_endpoint_config_t *config)
159 {
160 srtm_rpmsg_endpoint_t handle;
161
162 assert(config != NULL);
163 assert(config->rpmsgHandle != NULL);
164
165 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
166
167 handle = (srtm_rpmsg_endpoint_t)SRTM_Heap_Malloc(sizeof(struct _srtm_rpmsg_endpoint));
168 assert(handle != NULL);
169
170 handle->started = false;
171 handle->rxCallback = NULL;
172 handle->rxCallbackParam = NULL;
173 handle->rpmsgEndpoint =
174 rpmsg_lite_create_ept(config->rpmsgHandle, config->localAddr, SRTM_RPMsgEndpoint_RxHandler, handle);
175 assert(handle->rpmsgEndpoint != NULL);
176
177 (void)memcpy(&handle->config, config, sizeof(struct _srtm_rpmsg_endpoint_config));
178 if (config->localAddr == RL_ADDR_ANY)
179 {
180 handle->config.localAddr = handle->rpmsgEndpoint->addr;
181 }
182
183 SRTM_List_Init(&handle->channel.node);
184 handle->channel.core = NULL;
185 handle->channel.destroy = SRTM_RPMsgEndpoint_Destroy;
186 handle->channel.start = SRTM_RPMsgEndpoint_Start;
187 handle->channel.stop = SRTM_RPMsgEndpoint_Stop;
188 handle->channel.sendData = SRTM_RPMsgEndpoint_SendData;
189
190 if (config->epName != NULL)
191 {
192 if (rpmsg_ns_announce(config->rpmsgHandle, handle->rpmsgEndpoint, config->epName, (uint32_t)RL_NS_CREATE) !=
193 RL_SUCCESS)
194 {
195 assert((bool)false);
196 }
197 }
198
199 return &handle->channel;
200 }
201
SRTM_RPMsgEndpoint_Destroy(srtm_channel_t channel)202 void SRTM_RPMsgEndpoint_Destroy(srtm_channel_t channel)
203 {
204 srtm_rpmsg_endpoint_t handle = (srtm_rpmsg_endpoint_t)(void *)channel;
205
206 assert(channel != NULL);
207 assert(channel->core == NULL); /* Channel must be removed from core before destroy */
208 assert(SRTM_List_IsEmpty(&channel->node)); /* Channel must not on any list */
209
210 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
211
212 (void)rpmsg_lite_destroy_ept(handle->config.rpmsgHandle, handle->rpmsgEndpoint);
213
214 SRTM_Heap_Free(handle);
215 }
216
SRTM_RPMsgEndpoint_OverrideRxHandler(srtm_channel_t channel,srtm_rpmsg_endpoint_rx_cb_t callback,void * param)217 srtm_status_t SRTM_RPMsgEndpoint_OverrideRxHandler(srtm_channel_t channel,
218 srtm_rpmsg_endpoint_rx_cb_t callback,
219 void *param)
220 {
221 srtm_rpmsg_endpoint_t handle = (srtm_rpmsg_endpoint_t)(void *)channel;
222
223 assert(handle != NULL);
224
225 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
226
227 handle->rxCallback = callback;
228 handle->rxCallbackParam = param;
229
230 return SRTM_Status_Success;
231 }
232