f9e153a19745ff7a1eaaedbbb1897b3c1f06b096
[o-du/l2.git] / src / cm / cm_bdy5.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17 *******************************************************************************/
18
19 /********************************************************************20**
20
21      Name:     common functions - 5
22
23      Type:     C source file
24
25      Desc:     C source code for common timer routines;
26
27      File:     cm_bdy5.c
28
29 *********************************************************************21*/
30
31 \f
32 /* header include files -- defines (.h) */
33
34 #include "envopt.h"        /* environment options */
35 #include "envdep.h"        /* environment dependent */
36 #include "envind.h"        /* environment independent */
37
38 #include "gen.h"           /* general */
39 #include "ssi.h"           /* system services */
40 #include "cm5.h"           /* common functions */
41
42 /* header/extern include files (.x) */
43
44 #include "gen.x"           /* general */
45 #include "ssi.x"           /* system services */
46 #include "cm5.x"           /* common functions */
47
48 \f
49 /* local defines */
50
51 #define CM_RMV_TQCP(tqEnt, tgt)                            \
52 {                                                          \
53    ((tgt)->prev) ? ((tgt)->prev->next = (tgt)->next):      \
54                   ((tqEnt)->first = (tgt)->next);          \
55    ((tgt)->next) ? ((tgt)->next->prev = (tgt)->prev):      \
56                   ((tqEnt)->tail = (tgt)->prev);           \
57    (tgt)->prev = NULLP;                                    \
58    (tgt)->next = NULLP;                                    \
59    (tgt)->ent2bUpd = FALSE;                                \
60 }
61  
62 #define CM_PLC_TQCP(tqEnt, tgt)                            \
63 {                                                          \
64    if ((tqEnt)->tail)                                      \
65    {                                                       \
66       (tqEnt)->tail->next = tgt;                           \
67       (tgt)->prev = (tqEnt)->tail;                         \
68       (tqEnt)->tail = tgt;                                 \
69    }                                                       \
70    else                                                    \
71    {                                                       \
72       (tqEnt)->first = (tqEnt)->tail = tgt;                \
73    }                                                       \
74 }
75
76 /* local externs */
77
78 /* forward references */
79
80 /* functions in other modules */
81
82 \f
83 /*
84 *
85 *       Fun:   cmPrcTmr
86 *
87 *       Desc:  Handle a timer entry
88 *
89 *       Ret:   void
90 *
91 *       Notes: 
92 *
93 *       File:  cm_bdy5.c
94 *
95 */
96  
97 #ifdef SS_FAP
98 Void cmPrcTmr
99 (
100 CmTqCp   *tqCp,          /* timing que control point */
101 CmTqType *tq,            /* timing queue */
102 PFV      func            /* function */
103 )
104 {
105 /**/
106    uint32_t expire;
107    uint32_t entry;
108    S16 event;
109    PTR cb;
110    CmTimer *tmp1;
111    CmTimer **tmp2;
112  
113
114 #ifdef CMDBG
115 {
116    DateTime dt;
117    Txt prntBuf[PRNTSZE];
118
119    SGetDateTime(&dt);
120    /* Here the year was being printed as 2 letter value and hence did
121     * not represent accurate information.  It has been modified as
122     * recommended to include the offset of year 1900 used in all Trillium
123     * SSI implementations. Patch cmbdy5c_001.113
124     */
125    sprintf(prntBuf,"%s: date: %02d/%02d/%04d time: %02d:%02d:%02d\n",
126            msArgv[0],dt.month,dt.day,(int)(dt.year + 1900), dt.hour,
127            dt.min, dt.sec);
128    SPrint(prntBuf);
129 }
130 #endif
131
132    ++tqCp->nxtEnt;
133    expire = tqCp->nxtEnt;
134    /* cm_bdy5_c_002.113 - Modification for SRegCfgTmr support */
135    entry = (uint32_t) (expire % (uint32_t)(tqCp->tmrLen));
136
137    tmp2 = &tq[entry].first;
138    while ((tmp1 = *tmp2) != NULLP)
139    {
140       if (tmp1->tqExpire == expire)
141       {
142          event = tmp1->tmrEvnt;
143          cb = tmp1->cb;
144          /* remove and reset this timer control block */
145          (*tmp2) = tmp1->next;
146          tmp1->tmrEvnt = TMR_NONE;
147          tmp1->tqExpire = 0;
148          tmp1->cb = NULLP;
149          tmp1->next = NULLP;
150          func(cb, event);
151       }
152       else
153          tmp2 = &tmp1->next;
154    }
155    return;
156 } /* end of cmPrcTmr */
157
158 #else /* not defined SS_FAP */
159
160 Void cmPrcTmr
161 (
162 CmTqCp   *tqCp,          /* timing que control point */
163 CmTqType *tq,            /* timing queue */
164 PFV      func            /* function */
165 )
166 {
167 /**/
168    uint32_t expire;
169    uint32_t entry, entry1;
170    S16 event;
171    CmTqType *tqEnt, *tqEnt1; 
172    PTR cb;
173    CmTimer *tmp1;
174    volatile uint32_t     startTime = 0;
175    
176  
177    /*starting Task*/
178    SStartTask(&startTime, PID_CM_PRC_TMR);
179
180 #ifdef CMDBG
181 {
182    DateTime dt;
183    Txt prntBuf[PRNTSZE];
184  
185    SGetDateTime(&dt);
186    /* Here the year was being printed as 2 letter value and hence did
187     * not represent accurate information.  It has been modified as
188     * recommended to include the offset of year 1900 used in all Trillium
189     * SSI implementations.
190     */
191    sprintf(prntBuf,"%s: date: %02d/%02d/%04d time: %02d:%02d:%02d\n",
192            msArgv[0],dt.month,dt.day,(int)(dt.year + 1900), dt.hour, 
193            dt.min, dt.sec);
194    SPrint(prntBuf);
195 }
196 #endif
197  
198    ++tqCp->nxtEnt;
199    expire = tqCp->nxtEnt;
200         tqCp->tmrLen = 1;
201    entry = (uint32_t) (expire % (uint32_t)(tqCp->tmrLen));
202   
203    tqCp->tmp = (tqEnt = &tq[entry])->first;
204    while ((tmp1 = tqCp->tmp) != NULLP)
205    {
206       tqCp->tmp = tmp1->next;
207       /* SRIKY - Temp Fix to overcome timer not firing. Need to take */
208           /* care of wrap around case                                                    */
209       if ((tmp1->tqExpire <= expire) || (tmp1->ent2bUpd))
210       {
211          event = tmp1->tmrEvnt;
212          cb = tmp1->cb;
213  
214          if (!(tmp1->ent2bUpd))
215          {
216             CM_RMV_TQCP(tqEnt, tmp1);
217             tmp1->tmrEvnt = TMR_NONE; 
218             tmp1->tqExpire = 0;     
219             tmp1->cb = NULLP;      
220  
221             func(cb, event);
222          }
223          else
224          {
225             entry1 = (uint32_t) (tmp1->tqExpire % (uint32_t)(tqCp->tmrLen));
226             tqEnt1 = &tq[entry1];
227             CM_RMV_TQCP(tqEnt, tmp1);
228             tmp1->entIdx = entry1; 
229             CM_PLC_TQCP(tqEnt1, tmp1);
230          }
231       }
232    }
233
234    /*stoping Task*/
235    SStopTask(startTime, PID_CM_PRC_TMR);
236    return;
237 } /* end of cmPrcTmr */
238 #endif /* SS_FAP */
239
240
241 \f
242 /*
243 *
244 *       Fun:   cmInitTimers
245 *
246 *       Desc:  initialize timers
247 *
248 *       Ret:   void
249 *
250 *       Notes: Connection Oriented Control
251 *
252 *       File:  cm_bdy5.c
253 *
254 */
255 Void cmInitTimers
256 (
257 CmTimer *timers,     /* timer list */
258 uint8_t max               /* maximum tmrs */
259 )
260 {
261    CmTimer *tPtr;
262    REG1 uint8_t i;
263
264
265    for (i = 0, tPtr = timers; i < max; i++, tPtr++)
266    {
267       tPtr->tmrEvnt = TMR_NONE;
268       tPtr->tqExpire = 0;
269       tPtr->cb = 0;
270       tPtr->next = (struct cmTimer *)NULLP;
271       tPtr->prev = (struct cmTimer *)NULLP;
272       tPtr->ent2bUpd = FALSE;
273    }
274    return;
275 } /* end of cmInitTimers */
276
277 /*
278 *
279 *       Fun:    cmPlcCbTq
280 *
281 *       Desc:   Places Control Block on Timing Queue
282 *
283 *       Ret:    void
284 *
285 *       Notes:  None
286 *
287 *       File:   cm_bdy5.c
288 *
289 */
290   
291 Void cmPlcCbTq(CmTmrArg *arg)
292 {
293 /*added FAP modifications*/
294 #ifdef SS_FAP
295    REG1 uint8_t tmrNum;
296    /* cm_bdy5_c_001.main_20 - Modification for SRegCfgTmr support */
297    uint32_t ent;
298    uint32_t expire;
299    CmTimer **tmp;
300
301
302    expire = (arg->tqCp->nxtEnt + arg->wait);
303    /* cm_bdy5_c_002.113 - Modification for SRegCfgTmr support */
304    ent = (uint32_t)(expire % (uint32_t)(arg->tqCp->tmrLen));
305
306    for (tmrNum = 0; tmrNum < arg->max; tmrNum++)
307    {
308       if (arg->timers[tmrNum].tmrEvnt == TMR_NONE)
309       {
310          arg->timers[tmrNum].tmrEvnt = arg->evnt;
311          arg->timers[tmrNum].tqExpire = expire;
312          arg->timers[tmrNum].cb = arg->cb;
313          arg->timers[tmrNum].next = NULLP;
314
315          tmp = &(arg->tq[ent].first);
316          while (*tmp)
317             tmp = &((*tmp)->next);
318          *tmp = &arg->timers[tmrNum];
319
320          return;
321       }
322    }
323    return;
324 #else
325    REG1 uint8_t tmrNum;
326    uint32_t ent;
327    CmTqType *tq;
328    CmTimer  *target;
329    uint32_t expire;
330  
331    expire = (arg->tqCp->nxtEnt + arg->wait);
332    ent = (uint32_t)(expire % (uint32_t)(arg->tqCp->tmrLen));
333  
334    for (tmrNum = 0; tmrNum < arg->max; tmrNum++)
335    {
336       if (arg->timers[tmrNum].tmrEvnt == TMR_NONE)
337       {
338          target = &arg->timers[tmrNum];
339          tq = &arg->tq[ent]; 
340  
341          target->tmrEvnt = arg->evnt;
342          target->tqExpire = expire;
343          target->cb = arg->cb;
344          target->ent2bUpd = FALSE;
345          target->entIdx   = ent;
346
347          /* Place the timer block in the timer list */
348          CM_PLC_TQCP(tq, target); 
349  
350          return;
351       }
352    }
353    return;
354 #endif
355 } /* end of cmPlcCbTq */
356  
357 /*
358 *
359 *       Fun:    cmRstCbTq
360 *
361 *       Desc:   Places Control Block on Timing Queue
362 *
363 *       Ret:    void
364 *
365 *       Notes:  None
366 *
367 *       File:   cm_bdy5.c
368 *
369 */
370   
371 Void cmRstCbTq(CmTmrArg *arg)
372 {
373  
374    arg->timers[arg->tNum].tqExpire = arg->tqCp->nxtEnt + arg->wait;
375    arg->timers[arg->tNum].ent2bUpd = TRUE; 
376  
377    return;
378 } /* end of cmRstCbTq */
379
380 /*
381 *
382 *       Fun:    cmRmvCbTq
383 *
384 *       Desc:   Removes control block from Timing Queue
385 *
386 *       Ret:    void
387 *
388 *       Notes:  None
389 *
390 *       File:   cm_bdy5.c
391 *
392 */
393   
394 Void cmRmvCbTq(CmTmrArg *arg)
395 {
396 /*Added FAP modifications*/
397 #ifdef SS_FAP
398 /* cm_bdy5_c_002.113 - Modification for SRegCfgTmr support */
399    uint32_t ent;
400    CmTimer *target;
401    CmTimer *tmp1;
402    CmTimer **tmp2;
403
404
405    target = &arg->timers[arg->tNum];
406    if (target->tmrEvnt != TMR_NONE)
407    {
408       /* cm_bdy5_c_002.113 - Modification for SRegCfgTmr support */
409       ent = (uint32_t) (target->tqExpire % (uint32_t)(arg->tqCp->tmrLen));
410       tmp2 = &arg->tq[ent].first;
411
412       while ((tmp1 = *tmp2) != NULLP)
413       {
414          if (tmp1 == target)
415          {
416             /* find the timer control block to be removed */
417             (*tmp2) = tmp1->next;
418             tmp1->tmrEvnt = TMR_NONE;
419             tmp1->tqExpire = 0;
420             tmp1->cb = NULLP;
421             tmp1->next = NULLP;
422             break;
423          }
424          else
425             /* find the next timer control block */
426             tmp2 = &tmp1->next;
427       }
428    }
429    return;
430 #else
431    uint32_t ent;
432    CmTimer  *target;
433    CmTqType *tq;
434    
435    target = &arg->timers[arg->tNum];
436    if (target->tmrEvnt != TMR_NONE)
437    {
438       ent = (uint32_t) (target->entIdx);
439       tq = &arg->tq[ent];
440  
441       /* 
442        * Update the timer pointer in the for correct processing in
443        * CmPrcTmr.
444        */
445       if (target == arg->tqCp->tmp)
446          arg->tqCp->tmp = target->next;
447  
448       /* Remove the entru from the list */
449       CM_RMV_TQCP( tq , target);
450       target->tmrEvnt = TMR_NONE;
451       target->tqExpire = 0;
452       target->cb = NULLP;
453  
454    }
455    return;
456 #endif
457 } /* end of cmRmvCbTq */
458  
459 /**********************************************************************
460          End of file
461 **********************************************************************/