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