Updated GDB ini file to load binding symbols directly from SDK
[apps/agl-service-unicens.git] / ucs2-lib / src / ucs_mgr.c
1 /*------------------------------------------------------------------------------------------------*/
2 /* UNICENS V2.1.0-3491                                                                            */
3 /* Copyright (c) 2017 Microchip Technology Germany II GmbH & Co. KG.                              */
4 /*                                                                                                */
5 /* This program is free software: you can redistribute it and/or modify                           */
6 /* it under the terms of the GNU General Public License as published by                           */
7 /* the Free Software Foundation, either version 2 of the License, or                              */
8 /* (at your option) any later version.                                                            */
9 /*                                                                                                */
10 /* This program is distributed in the hope that it will be useful,                                */
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of                                 */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                  */
13 /* GNU General Public License for more details.                                                   */
14 /*                                                                                                */
15 /* You should have received a copy of the GNU General Public License                              */
16 /* along with this program.  If not, see <http://www.gnu.org/licenses/>.                          */
17 /*                                                                                                */
18 /* You may also obtain this software under a propriety license from Microchip.                    */
19 /* Please contact Microchip for further information.                                              */
20 /*------------------------------------------------------------------------------------------------*/
21
22 /*!
23  * \file
24  * \brief Implementation of CManager class
25  *
26  * \cond UCS_INTERNAL_DOC
27  * \addtogroup  G_MGR
28  * @{
29  */
30
31 /*------------------------------------------------------------------------------------------------*/
32 /* Includes                                                                                       */
33 /*------------------------------------------------------------------------------------------------*/
34 #include "ucs_mgr.h"
35 #include "ucs_misc.h"
36 #include "ucs_scheduler.h"
37 #include "ucs_trace.h"
38
39 /*------------------------------------------------------------------------------------------------*/
40 /* Internal constants                                                                             */
41 /*------------------------------------------------------------------------------------------------*/
42 /*! \brief Priority of the Application Message Service */
43 static const uint8_t     MGR_SRV_PRIO       = 245U;         /* parasoft-suppress  MISRA2004-8_7 "configuration property" */
44 /*! \brief Event which triggers the service */
45 static const Srv_Event_t MGR_SRV_EV_SERVICE  = 1U;
46
47 /*! \brief Network status mask */
48 static const uint32_t    MGR_NWSTATUS_MASK = 0x0FU;         /* parasoft-suppress  MISRA2004-8_7 "configuration property" */
49 /*! \brief The time in milliseconds the INIC will go to AutoForcedNA after sync lost. */
50 static const uint16_t    MGR_AUTOFORCED_NA_TIME = 5000U;    /* parasoft-suppress  MISRA2004-8_7 "configuration property" */
51
52
53 /*------------------------------------------------------------------------------------------------*/
54 /* Internal prototypes                                                                            */
55 /*------------------------------------------------------------------------------------------------*/
56 static void Mgr_OnInitComplete(void *self, void *error_code_ptr);
57 static void Mgr_OnNwStatus(void *self, void *data_ptr);
58 static void Mgr_OnJobQResult(void *self, void *result_ptr);
59 static void Mgr_Startup(void *self);
60 static void Mgr_OnNwStartupResult(void *self, void *result_ptr);
61 static void Mgr_LeaveForcedNA(void *self);
62 static void Mgr_OnLeaveForcedNAResult(void *self, void *result_ptr);
63 #if 0
64 static void Mgr_Shutdown(void *self);
65 static void Mgr_OnNwShutdownResult(void *self, void *result_ptr);
66 #endif
67
68 /*------------------------------------------------------------------------------------------------*/
69 /* Class methods                                                                                  */
70 /*------------------------------------------------------------------------------------------------*/
71 /*! \brief Constructor of Manager class 
72  *  \param self         The instance
73  *  \param base_ptr     Reference to base component
74  *  \param inic_ptr     Reference to INIC component
75  *  \param net_ptr      Reference to net component
76  *  \param nd_ptr       Reference to NodeDiscovery component
77  *  \param packet_bw    Desired packet bandwidth
78  */
79 void Mgr_Ctor(CManager *self, CBase *base_ptr, CInic *inic_ptr, CNetworkManagement *net_ptr, CNodeDiscovery *nd_ptr, uint16_t packet_bw)
80 {
81     MISC_MEM_SET(self, 0, sizeof(*self));
82
83     self->initial = true;
84     self->base_ptr = base_ptr;
85     self->inic_ptr = inic_ptr;
86     self->net_ptr = net_ptr;
87     self->nd_ptr = nd_ptr;
88     self->packet_bw = packet_bw;
89
90     Jbs_Ctor(&self->job_service, base_ptr);
91     Job_Ctor(&self->job_leave_forced_na, &Mgr_LeaveForcedNA, self);
92     Job_Ctor(&self->job_startup, &Mgr_Startup, self);
93 #if 0
94     Job_Ctor(&self->job_shutdown, &Mgr_Shutdown, self);
95 #endif
96
97     self->list_startup[0] = &self->job_startup;
98     self->list_startup[1] = NULL;
99     self->list_force_startup[0] = &self->job_leave_forced_na;
100     self->list_force_startup[1] = &self->job_startup;
101     self->list_force_startup[2] = NULL;
102 #if 0
103     self->list_shutdown[0] = &self->job_shutdown;
104     self->list_shutdown[1] = NULL;
105 #endif
106
107     Jbq_Ctor(&self->job_q_startup, &self->job_service, 1U, self->list_startup);
108     Jbq_Ctor(&self->job_q_force_startup, &self->job_service, 2U, self->list_force_startup);
109 #if 0
110     Jbq_Ctor(&self->job_q_shutdown, &self->job_service, 4U, self->list_shutdown);
111 #endif
112
113     Sobs_Ctor(&self->startup_obs, self, &Mgr_OnNwStartupResult);
114     Sobs_Ctor(&self->force_na_obs, self, &Mgr_OnLeaveForcedNAResult);
115 #if 0
116     Sobs_Ctor(&self->shutdown_obs, self, &Mgr_OnNwShutdownResult);
117 #endif
118     Sobs_Ctor(&self->job_q_obs, self, &Mgr_OnJobQResult);
119
120     Mobs_Ctor(&self->event_observer, self, EH_E_INIT_SUCCEEDED, &Mgr_OnInitComplete);
121     Eh_AddObsrvInternalEvent(&self->base_ptr->eh, &self->event_observer);
122     Mobs_Ctor(&self->nwstatus_mobs, self, MGR_NWSTATUS_MASK, &Mgr_OnNwStatus);
123 }
124
125 /*------------------------------------------------------------------------------------------------*/
126 /* Callback Methods                                                                               */
127 /*------------------------------------------------------------------------------------------------*/
128 /*! \brief  Callback function which is invoked if the initialization is complete
129  *  \param  self            The instance
130  *  \param  error_code_ptr  Reference to the error code
131  */
132 static void Mgr_OnInitComplete(void *self, void *error_code_ptr)
133 {
134     CManager *self_ = (CManager*)self;
135     MISC_UNUSED(error_code_ptr);
136
137     TR_INFO((self_->base_ptr->ucs_user_ptr, "[MGR]", "Received init complete event", 0U));
138     Net_AddObserverNetworkStatus(self_->net_ptr, &self_->nwstatus_mobs);    /* register observer */
139     (void)Nd_Start(self_->nd_ptr);
140 }
141
142 /*! \brief      NetworkStatus callback function
143  *  \details    The function is only active if \c listening flag is \c true.
144  *              This avoids to re-register und un-register the observer for several times.
145  *  \param      self        The instance
146  *  \param      data_ptr   Reference to \ref Net_NetworkStatusParam_t
147  */
148 static void Mgr_OnNwStatus(void *self, void *data_ptr)
149 {
150     CManager *self_ = (CManager*)self;
151     Net_NetworkStatusParam_t *param_ptr = (Net_NetworkStatusParam_t *)data_ptr;
152
153     TR_INFO((self_->base_ptr->ucs_user_ptr, "[MGR]", "Mgr_OnNwStatus()", 0U));
154
155     TR_INFO((self_->base_ptr->ucs_user_ptr, "[MGR]", "Mgr_OnNwStatus(): mask=0x%04X, events=0x%04X", 2U, param_ptr->change_mask ,param_ptr->events));
156     TR_INFO((self_->base_ptr->ucs_user_ptr, "[MGR]", "Mgr_OnNwStatus(): avail=0x%X, avail_i=0x%X, bw=0x%X", 3U, param_ptr->availability, param_ptr->avail_info, param_ptr->packet_bw));
157     TR_INFO((self_->base_ptr->ucs_user_ptr, "[MGR]", "Mgr_OnNwStatus(): addr=0x%03X, pos=0x%X, mpr=0x%X", 3U, param_ptr->node_address, param_ptr->node_position, param_ptr->max_position));
158
159     if ((param_ptr->change_mask & ((uint16_t)UCS_NW_M_AVAIL | (uint16_t)UCS_NW_M_PACKET_BW)) != 0U)
160     {
161         TR_INFO((self_->base_ptr->ucs_user_ptr, "[MGR]", "Mgr_OnNwStatus(): trigger event", 0U));
162
163         if (self_->current_q_ptr != NULL)
164         {
165             Jbq_Stop(self_->current_q_ptr);
166         }
167
168         if (param_ptr->avail_info == UCS_NW_AVAIL_INFO_FORCED_NA)
169         {
170             self_->current_q_ptr = &self_->job_q_force_startup;         /* stop forcing NA, then startup */
171             Jbq_Start(&self_->job_q_force_startup, &self_->job_q_obs);
172         }
173         else if (param_ptr->availability == UCS_NW_NOT_AVAILABLE)
174         {
175             self_->current_q_ptr = &self_->job_q_startup;               /* just startup */
176             Jbq_Start(&self_->job_q_startup, &self_->job_q_obs);
177         }
178 #if 0
179         else if ((param_ptr->node_position != 0U) || (param_ptr->packet_bw != self_->packet_bw))
180         {
181             self_->current_q_ptr = &self_->job_q_shutdown;              /* just shutdown - startup is triggered automatically */
182             Jbq_Start(&self_->job_q_shutdown, &self_->job_q_obs);
183         }
184 #endif       
185         if (self_->initial != false)
186         {
187             self_->initial = false;
188             if (self_->current_q_ptr == NULL)                           /* trigger InitAll() if no job is required for the */
189             {                                                           /* initial network status notification */
190                 Nd_InitAll(self_->nd_ptr);
191             }
192         }
193     }
194 }
195
196 /*! \brief      Callback function that is triggered after finished a job.
197  *  \details    Failed jobs will be restarted here.
198  *  \param      self        The instance
199  *  \param      result_ptr  Reference to the job result \ref Job_Result_t.
200  */
201 static void Mgr_OnJobQResult(void *self, void *result_ptr)
202 {
203     CManager *self_ = (CManager*)self;
204     Job_Result_t *res = (Job_Result_t *)result_ptr;
205     TR_INFO((self_->base_ptr->ucs_user_ptr, "[MGR]", "Mgr_OnJobQResult(): result=%d", 1U, *res));
206
207     if ((*res != JOB_R_SUCCESS) && (self_->current_q_ptr != NULL))
208     {
209         Jbq_Start(self_->current_q_ptr, &self_->job_q_obs);
210     }
211     else
212     {
213         self_->current_q_ptr = NULL;
214     }
215 }
216
217
218 /*------------------------------------------------------------------------------------------------*/
219 /* Job: LeaveForcedNA                                                                             */
220 /*------------------------------------------------------------------------------------------------*/
221 /*! \brief      Action that sets the INIC from "Forced-NotAvailable" to "NotAvailable"
222  *  \param      self    The instance
223  */
224 static void Mgr_LeaveForcedNA(void *self)
225 {
226     CManager *self_ = (CManager*)self;
227     Ucs_Return_t ret;
228
229     TR_INFO((self_->base_ptr->ucs_user_ptr, "[MGR]", "Mgr_LeaveForcedNA()", 0U));
230     ret = Inic_NwForceNotAvailable(self_->inic_ptr, false /*no longer force NA*/, &self_->force_na_obs);
231
232     if (ret != UCS_RET_SUCCESS)
233     {
234         TR_ERROR((self_->base_ptr->ucs_user_ptr, "[MGR]", "Mgr_LeaveForcedNA(), function returns 0x%02X", 1U, ret));
235         Job_SetResult(&self_->job_leave_forced_na, JOB_R_FAILED);
236     }
237 }
238
239 /*! \brief  Callback function which announces the result of Inic_NwForceNotAvailable()
240  *  \param  self         The instance
241  *  \param  result_ptr   Reference to result. Must be casted into Inic_StdResult_t.
242  */
243 static void Mgr_OnLeaveForcedNAResult(void *self, void *result_ptr)
244 {
245     CManager *self_ = (CManager*)self;
246     Inic_StdResult_t *result_ptr_ = (Inic_StdResult_t *)result_ptr;
247
248     TR_INFO((self_->base_ptr->ucs_user_ptr, "[MGR]", "Mgr_OnLeaveForcedNAResult(): code=0x%02X", 1U, result_ptr_->result.code));
249
250     if (result_ptr_->result.code == UCS_RES_SUCCESS)
251     {
252         Job_SetResult(&self_->job_leave_forced_na, JOB_R_SUCCESS);
253     }
254     else
255     {
256         Job_SetResult(&self_->job_leave_forced_na, JOB_R_FAILED);
257     }
258 }
259
260 /*------------------------------------------------------------------------------------------------*/
261 /* Job: Startup                                                                                   */
262 /*------------------------------------------------------------------------------------------------*/
263 /*! \brief      Action that starts the network with the given parameters
264  *  \param      self    The instance
265  */
266 static void Mgr_Startup(void *self)
267 {
268     CManager *self_ = (CManager*)self;
269     Ucs_Return_t ret;
270
271     TR_INFO((self_->base_ptr->ucs_user_ptr, "[MGR]", "Mgr_Startup()", 0U));
272     ret = Inic_NwStartup(self_->inic_ptr, MGR_AUTOFORCED_NA_TIME, self_->packet_bw, &self_->startup_obs);    /* Startup without ForcedNA */
273
274     if (ret != UCS_RET_SUCCESS)
275     {
276         TR_ERROR((self_->base_ptr->ucs_user_ptr, "[MGR]", "Mgr_Startup(), startup returns 0x%02X", 1U, ret));
277         Job_SetResult(&self_->job_startup, JOB_R_FAILED);
278     }
279 }
280
281 /*! \brief  Callback function which announces the result of Net_NetworkStartup()
282  *  \param  self         The instance
283  *  \param  result_ptr   Reference to result. Must be casted into Inic_StdResult_t.
284  */
285 static void Mgr_OnNwStartupResult(void *self, void *result_ptr)
286 {
287     CManager *self_ = (CManager*)self;
288     Inic_StdResult_t *result_ptr_ = (Inic_StdResult_t *)result_ptr;
289
290     TR_INFO((self_->base_ptr->ucs_user_ptr, "[MGR]", "Mgr_OnNwStartupResult(): code=0x%02X", 1U, result_ptr_->result.code));
291
292     if (result_ptr_->result.code == UCS_RES_SUCCESS)
293     {
294         Job_SetResult(&self_->job_startup, JOB_R_SUCCESS);
295     }
296     else
297     {
298         Job_SetResult(&self_->job_startup, JOB_R_FAILED);
299     }
300 }
301
302 /*------------------------------------------------------------------------------------------------*/
303 /* Job: Shutdown                                                                                  */
304 /*------------------------------------------------------------------------------------------------*/
305 #if 0
306 /*! \brief      Action that performs a network shutdown.
307  *  \param      self    The instance
308  */
309 static void Mgr_Shutdown(void *self)
310 {
311     CManager *self_ = (CManager*)self;
312     Ucs_Return_t ret;
313
314     TR_INFO((self_->base_ptr->ucs_user_ptr, "[MGR]", "Mgr_Shutdown()", 0U));
315     ret = Inic_NwShutdown(self_->inic_ptr, &self_->shutdown_obs);
316
317     if (ret != UCS_RET_SUCCESS)
318     {
319         TR_ERROR((self_->base_ptr->ucs_user_ptr, "[MGR]", "Mgr_Shutdown(), shutdown returns 0x%02X", 1U, ret));
320         Job_SetResult(&self_->job_shutdown, JOB_R_FAILED);
321     }
322 }
323
324 /*! \brief  Callback function which announces the result of Net_NetworkShutdown()
325  *  \param  self        The instance
326  *  \param  result_ptr  Reference to result. Must be casted into Inic_StdResult_t.
327  */
328 static void Mgr_OnNwShutdownResult(void *self, void *result_ptr)
329 {
330     CManager *self_ = (CManager*)self;
331     Inic_StdResult_t *result_ptr_ = (Inic_StdResult_t *)result_ptr;
332
333     TR_INFO((self_->base_ptr->ucs_user_ptr, "[MGR]", "Mgr_OnNwShutdownResult(): code=0x%02X", 1U, result_ptr_->result.code));
334
335     if (result_ptr_->result.code == UCS_RES_SUCCESS)
336     {
337         Job_SetResult(&self_->job_shutdown, JOB_R_SUCCESS);
338     }
339     else
340     {
341         Job_SetResult(&self_->job_shutdown, JOB_R_FAILED);
342     }
343 }
344 #endif
345
346 /*!
347  * @}
348  * \endcond
349  */
350
351 /*------------------------------------------------------------------------------------------------*/
352 /* End of file                                                                                    */
353 /*------------------------------------------------------------------------------------------------*/
354