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