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