1 /*
2 * Copyright 2017, NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include <string.h>
10
11 #include "srtm_heap.h"
12 #include "srtm_peercore.h"
13 #include "srtm_peercore_struct.h"
14 #include "srtm_channel.h"
15 #include "srtm_channel_struct.h"
16 #include "srtm_dispatcher.h"
17 #include "srtm_dispatcher_struct.h"
18
19 /*******************************************************************************
20 * Definitions
21 ******************************************************************************/
22
23 /*******************************************************************************
24 * Prototypes
25 ******************************************************************************/
26
27 /*******************************************************************************
28 * Variables
29 ******************************************************************************/
30
31 /*******************************************************************************
32 * Code
33 ******************************************************************************/
SRTM_PeerCore_Create(uint32_t id)34 srtm_peercore_t SRTM_PeerCore_Create(uint32_t id)
35 {
36 srtm_peercore_t core = (srtm_peercore_t)SRTM_Heap_Malloc(sizeof(struct _srtm_peercore));
37 #if defined(SRTM_STATIC_API) && SRTM_STATIC_API
38 srtm_mutex_t mutex = SRTM_Mutex_Create(&core->mutexStatic);
39 #else
40 srtm_mutex_t mutex = SRTM_Mutex_Create();
41 #endif
42
43 assert((core != NULL) && (mutex != NULL));
44
45 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
46 SRTM_List_Init(&core->node);
47 SRTM_List_Init(&core->channels);
48 SRTM_List_Init(&core->pendingQ);
49
50 core->id = id;
51 core->dispatcher = NULL;
52 core->mutex = mutex;
53 core->started = false;
54 core->state = SRTM_PeerCore_State_Inactive;
55 core->wakeupFunc = NULL;
56 core->wakeupParam = NULL;
57
58 return core;
59 }
60
SRTM_PeerCore_Destroy(srtm_peercore_t core)61 void SRTM_PeerCore_Destroy(srtm_peercore_t core)
62 {
63 srtm_channel_t channel;
64 srtm_list_t *list;
65
66 assert(core);
67 assert(!core->started);
68
69 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
70
71 while (!SRTM_List_IsEmpty(&core->channels))
72 {
73 list = core->channels.next;
74 SRTM_List_Remove(list);
75 channel = SRTM_LIST_OBJ(srtm_channel_t, node, list);
76 channel->core = NULL;
77 SRTM_Channel_Destroy(channel);
78 }
79
80 /* Pending Q must be cleaned by SRTM before removing peer core from it */
81 assert(SRTM_List_IsEmpty(&core->pendingQ));
82
83 SRTM_Mutex_Destroy(core->mutex);
84 SRTM_Heap_Free(core);
85 }
86
SRTM_PeerCore_GetID(srtm_peercore_t core)87 uint32_t SRTM_PeerCore_GetID(srtm_peercore_t core)
88 {
89 assert(core);
90
91 return core->id;
92 }
93
SRTM_PeerCore_Start(srtm_peercore_t core)94 srtm_status_t SRTM_PeerCore_Start(srtm_peercore_t core)
95 {
96 srtm_status_t status = SRTM_Status_Success;
97 srtm_channel_t channel;
98 srtm_list_t *list;
99
100 assert(core);
101
102 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
103
104 if (core->started)
105 {
106 return SRTM_Status_InvalidState;
107 }
108
109 core->started = true;
110
111 for (list = core->channels.next; list != &core->channels; list = list->next)
112 {
113 channel = SRTM_LIST_OBJ(srtm_channel_t, node, list);
114 status = SRTM_Channel_Start(channel);
115 }
116
117 return status;
118 }
119
SRTM_PeerCore_Stop(srtm_peercore_t core)120 srtm_status_t SRTM_PeerCore_Stop(srtm_peercore_t core)
121 {
122 srtm_status_t status = SRTM_Status_Success;
123 srtm_channel_t channel;
124 srtm_list_t *list;
125
126 assert(core);
127
128 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
129
130 if (!core->started)
131 {
132 return SRTM_Status_InvalidState;
133 }
134
135 core->started = false;
136
137 for (list = core->channels.next; list != &core->channels; list = list->next)
138 {
139 channel = SRTM_LIST_OBJ(srtm_channel_t, node, list);
140 status = SRTM_Channel_Stop(channel);
141 }
142
143 return status;
144 }
145
SRTM_PeerCore_Activate(srtm_peercore_t core)146 srtm_status_t SRTM_PeerCore_Activate(srtm_peercore_t core)
147 {
148 srtm_status_t status = SRTM_Status_Success;
149
150 assert(core);
151
152 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
153
154 if (core->wakeupFunc != NULL)
155 {
156 status = core->wakeupFunc(core, core->wakeupParam);
157 }
158
159 if (status == SRTM_Status_Success)
160 {
161 core->state = SRTM_PeerCore_State_Activating;
162 }
163
164 /* Only Life Cycle Service knows about the real state of peer core when processing
165 peer core request, so it will take responsibility to change the state to ACTIVATED */
166
167 return status;
168 }
169
SRTM_PeerCore_Deactivate(srtm_peercore_t core,srtm_peercore_wakeup_cb_t wakeup,void * param)170 srtm_status_t SRTM_PeerCore_Deactivate(srtm_peercore_t core, srtm_peercore_wakeup_cb_t wakeup, void *param)
171 {
172 assert(core);
173
174 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s\r\n", __func__);
175
176 core->wakeupFunc = wakeup;
177 core->wakeupParam = param;
178
179 core->state = SRTM_PeerCore_State_Deactivating;
180
181 /* Only application knows about the real state of peer core when querying the peer
182 core status, so it will take responsibility to change the state to DEACTIVATED */
183
184 return SRTM_Status_Success;
185 }
186
SRTM_PeerCore_AddChannel(srtm_peercore_t core,srtm_channel_t channel)187 srtm_status_t SRTM_PeerCore_AddChannel(srtm_peercore_t core, srtm_channel_t channel)
188 {
189 assert(core);
190 assert(channel);
191 assert(!core->started); /* Add channel when SRTM dispatcher running is forbidden */
192
193 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s: 0x%x\r\n", __func__, channel);
194
195 if (!SRTM_List_IsEmpty(&channel->node))
196 {
197 return SRTM_Status_ListAddFailed;
198 }
199
200 (void)SRTM_Mutex_Lock(core->mutex);
201 SRTM_List_AddTail(&core->channels, &channel->node);
202 (void)SRTM_Mutex_Unlock(core->mutex);
203 channel->core = core;
204
205 return SRTM_Status_Success;
206 }
207
SRTM_PeerCore_RemoveChannel(srtm_peercore_t core,srtm_channel_t channel)208 srtm_status_t SRTM_PeerCore_RemoveChannel(srtm_peercore_t core, srtm_channel_t channel)
209 {
210 assert(core);
211 assert(channel);
212 assert(!core->started); /* Remove channel when SRTM dispatcher running is forbidden */
213
214 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s: 0x%x\r\n", __func__, channel);
215
216 if (SRTM_List_IsEmpty(&channel->node))
217 {
218 return SRTM_Status_ListRemoveFailed;
219 }
220
221 (void)SRTM_Mutex_Lock(core->mutex);
222 SRTM_List_Remove(&channel->node);
223 (void)SRTM_Mutex_Unlock(core->mutex);
224 channel->core = NULL;
225
226 return SRTM_Status_Success;
227 }
228
SRTM_PeerCore_GetState(srtm_peercore_t core)229 srtm_peercore_state_t SRTM_PeerCore_GetState(srtm_peercore_t core)
230 {
231 assert(core);
232
233 return core->state;
234 }
235
SRTM_PeerCore_SetState(srtm_peercore_t core,srtm_peercore_state_t state)236 srtm_status_t SRTM_PeerCore_SetState(srtm_peercore_t core, srtm_peercore_state_t state)
237 {
238 assert(core);
239
240 SRTM_DEBUG_MESSAGE(SRTM_DEBUG_VERBOSE_INFO, "%s: %d\r\n", __func__, state);
241
242 core->state = state;
243
244 return SRTM_Status_Success;
245 }
246