comparison gsm-fw/g23m-gsm/alr/alr_em.c @ 673:2f7df7a314f8

gsm-fw/g23m-gsm subtree: initial import from LoCosto source
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 28 Sep 2014 23:20:04 +0000
parents
children a2a65fdc1a99
comparison
equal deleted inserted replaced
672:0dc6f9e8e980 673:2f7df7a314f8
1 /*
2 +-----------------------------------------------------------------------------
3 | Project :
4 | Modul :
5 +-----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +-----------------------------------------------------------------------------
17 | Purpose : This Module defines the engineering mode (EM) device driver for the
18 | G23 protocol stack. This driver is used to control all engineering
19 | mode related functions.
20 +-----------------------------------------------------------------------------
21 */
22
23 #ifndef ALR_EM_C
24 #define ALR_EM_C
25
26 #define ENTITY_PL
27
28 /*==== INCLUDES ===================================================*/
29 #include <string.h>
30 #include <stdlib.h>
31 #include <ctype.h>
32 #include "typedefs.h"
33 #include "pconst.cdg"
34 #include "mconst.cdg"
35 #include "message.h"
36 #include "ccdapi.h"
37 #include "vsi.h"
38 #include "custom.h"
39 #include "gsm.h"
40 #include "prim.h"
41 #include "cnf_alr.h"
42 #include "mon_alr.h"
43 #include "pei.h"
44 #include "tok.h"
45 #include "pcm.h"
46
47 #ifdef GPRS
48 #include "alr_gprs.h"
49 #endif
50
51 #ifdef GPRS
52 #ifdef _TARGET_
53 #include "inth/iq.h"
54 #endif
55 /*
56 * obsolete (msb / 2002-04-25)
57 #include "armio/armio.h"
58 */
59 #endif
60
61 #include "alr.h"
62 #include "alr_em.h"
63
64
65 /*==== IMPORT =====================================================*/
66
67 /*==== EXPORT =====================================================*/
68
69 /*==== PRIVAT =====================================================*/
70
71 /*==== VARIABLES ==================================================*/
72 #if defined (FF_EM_MODE) AND defined (ALR)
73
74 /* Event tracing flags for EM */
75 GLOBAL BOOL alr_v[EM_MAX_ALR_EVENTS];
76
77 LOCAL UBYTE em_alr_trace_occured = 0;
78
79
80 /*
81 These variables are used between entities. Even this is not a clean solution it is a straigth forward
82 way to reduce the overhead to a minimum. A clean solution would be based on an only usage of primitives
83 which would stress the os with no aditional advantage!!
84 */
85 GLOBAL volatile UBYTE em_l1_sem_buffer [EM_L1_SEM_SIZE]; /*lint -esym(765,em_l1_sem_buffer) | external could be made static | used externally */
86 GLOBAL volatile UBYTE em_l1_sem_index = 0; /*lint -esym(765,em_l1_sem_index) | external could be made static | used externally */
87
88 static T_HANDLE sem_EM_L1;
89
90 #define ENTER_CRITICAL_SECTION(sem) if (alr_em_enter_critical_section(sem))return FALSE;
91 #define LEAVE_CRITICAL_SECTION(sem) if (alr_em_leave_critical_section(sem))return FALSE;
92
93 #endif /* FF_EM_MODE */
94
95 /*==== FUNCTIONS ==================================================*/
96 #if defined (FF_EM_MODE) AND defined (ALR)
97
98 LOCAL UBYTE em_l1_sem (UBYTE length, UBYTE * data);
99 LOCAL int em_l1_sem_clear (void);
100 LOCAL void alr_em_first_event_check (void); /*Check for ACI - Notification*/
101
102 static void alr_em_semaphore_err (void);
103
104 #if !defined(SYST_TRACE)
105 #define SYST_TRACE(a) vsi_o_ttrace(0, TC_SYSTEM, a);
106 #endif /* !SYST_TRACE */
107
108 static int alr_em_enter_critical_section (T_HANDLE sem);
109 static int alr_em_leave_critical_section (T_HANDLE sem);
110
111
112 /*
113 +------------------------------------------------------------------------------
114 | Function : em_init_l1_event_trace
115 +------------------------------------------------------------------------------
116 | Description : Initialize the event tracing flags
117 |
118 | Parameters :
119 |
120 | Return :
121 |
122 +------------------------------------------------------------------------------
123 */
124 GLOBAL void em_init_l1_event_trace(void)
125 {
126 UBYTE i;
127
128 TRACE_FUNCTION("em_init_l1_event_trace ()");
129
130 for(i=0; i<EM_MAX_ALR_EVENTS; i++)
131 alr_v[i] = 0;
132 }
133
134 /*
135 +------------------------------------------------------------------------------
136 | Function : l1_em_l1_event_req
137 +------------------------------------------------------------------------------
138 | Description : Set the event tracing flags according the bitmask
139 |
140 | Parameters : Primitive - Bitmask
141 |
142 | Return :
143 |
144 +------------------------------------------------------------------------------
145 */
146
147 GLOBAL void l1_em_l1_event_req (T_EM_L1_EVENT_REQ *em_l1_event_req)
148 {
149 UBYTE i;
150
151 TRACE_FUNCTION("l1_em_l1_event_req ()");
152
153 /*
154 * The event tracing flags are set according the bitmask. alr_v[i] are
155 * the flags belonging to the event number described in 8443.601
156 */
157 for(i=1; i<33; i++) {
158 alr_v[i] = ((em_l1_event_req->bitmask_l1_l & (0x01<<(i-1))) > 0) ? TRUE : FALSE;
159 }
160
161 for(i=33; i<(EM_MAX_ALR_EVENTS); i++) {
162 alr_v[i] = ((em_l1_event_req->bitmask_l1_h & (0x01<<(i-1))) > 0) ? TRUE : FALSE;
163 }
164
165 /*
166 * A new event trace is generated therefor the flag is set to zero.
167 */
168 em_alr_trace_occured = 0;
169
170 PFREE(em_l1_event_req);
171 }
172
173 /*
174 +------------------------------------------------------------------------------
175 | Function : em_write_buffer_2
176 +------------------------------------------------------------------------------
177 | Description : Perform buffer check and store corresponding data in it.
178 |
179 | Parameters : Event number
180 |
181 | Return : TRUE/FALSE
182 |
183 +------------------------------------------------------------------------------
184 */
185 GLOBAL UBYTE em_write_buffer_2 (UBYTE event_no)
186 {
187 UBYTE em_l1_event_buffer[2];
188 UBYTE em_l1_buffer_write = 0;
189 UBYTE length = 2;
190
191 TRACE_FUNCTION("alr_em_write_buffer_2 ()");
192
193 /*
194 ACI is informed about the first event trace, used for later data processing.
195 */
196 alr_em_first_event_check();
197
198 memset(em_l1_event_buffer, 0, 2);
199
200 em_l1_event_buffer[em_l1_buffer_write++] = event_no; /* Event number */
201 em_l1_event_buffer[em_l1_buffer_write++] = length-2; /* Value length - 0 equals no data */
202
203 return (em_l1_sem (length, em_l1_event_buffer)); /* Data is stored inside buffer, reset flag */
204 }
205
206 /*
207 +------------------------------------------------------------------------------
208 | Function : em_write_buffer_3
209 +------------------------------------------------------------------------------
210 | Description : Perform buffer check and store corresponding data in it.
211 |
212 | Parameters : Event number, data value
213 |
214 | Return : TRUE/FALSE
215 |
216 +------------------------------------------------------------------------------
217 */
218 GLOBAL UBYTE em_write_buffer_3 (UBYTE event_no, UBYTE value)
219 {
220 UBYTE em_l1_event_buffer[3];
221 UBYTE em_l1_buffer_write = 0;
222 UBYTE length = 3;
223
224 TRACE_FUNCTION("alr_em_write_buffer_3 ()");
225
226 /*
227 ACI is informed about the first event trace, used for later data processing.
228 */
229 alr_em_first_event_check();
230
231 memset(em_l1_event_buffer, 0, 3);
232
233 em_l1_event_buffer[em_l1_buffer_write++] = event_no; /* Event number */
234 em_l1_event_buffer[em_l1_buffer_write++] = length-2; /* Value length - 0 equals no value */
235 em_l1_event_buffer[em_l1_buffer_write++] = value; /* Data to be stored */
236
237 return (em_l1_sem (length, em_l1_event_buffer)); /* Data is stored inside buffer, reset flag */
238 }
239
240 /*
241 +------------------------------------------------------------------------------
242 | Function : em_write_buffer_3a
243 +------------------------------------------------------------------------------
244 | Description : Perform buffer check and store corresponding data in it.
245 |
246 | Parameters : Event number, data value (USHORT)
247 |
248 | Return : TRUE/FALSE
249 |
250 +------------------------------------------------------------------------------
251 */
252 GLOBAL UBYTE em_write_buffer_3a (UBYTE event_no, USHORT value)
253 {
254 UBYTE em_l1_event_buffer[4];
255 UBYTE em_l1_buffer_write = 0;
256 UBYTE length = 4;
257
258 TRACE_FUNCTION("alr_em_write_buffer_4 ()");
259
260 /*
261 ACI is informed about the first event trace, used for later data processing.
262 */
263 alr_em_first_event_check();
264
265 memset(em_l1_event_buffer, 0, 4);
266
267 em_l1_event_buffer[em_l1_buffer_write++] = event_no; /* Event number */
268 em_l1_event_buffer[em_l1_buffer_write++] = length-2; /* Value length - 0 equals no value */
269 em_l1_event_buffer[em_l1_buffer_write++] = (UBYTE)(value >> 8); /* Data to be stored - MSB first */
270 em_l1_event_buffer[em_l1_buffer_write++] = (UBYTE)(value); /* LSB second */
271
272 return (em_l1_sem (length, em_l1_event_buffer)); /* Data is stored inside buffer, reset flag */
273 }
274
275 /*
276 +------------------------------------------------------------------------------
277 | Function : em_write_buffer_4
278 +------------------------------------------------------------------------------
279 | Description : Perform buffer check and store corresponding data in it.
280 |
281 | Parameters : Event number, data value1 & value2
282 |
283 | Return : TRUE/FALSE
284 |
285 +------------------------------------------------------------------------------
286 */
287 GLOBAL UBYTE em_write_buffer_4 (UBYTE event_no, UBYTE value1, UBYTE value2)
288 {
289 UBYTE em_l1_event_buffer[4];
290 UBYTE em_l1_buffer_write = 0;
291 UBYTE length = 4;
292
293 TRACE_FUNCTION("alr_em_write_buffer_4 ()");
294
295 /*
296 ACI is informed about the first event trace, used for later data processing.
297 */
298 alr_em_first_event_check();
299
300 memset(em_l1_event_buffer, 0, 4);
301
302 em_l1_event_buffer[em_l1_buffer_write++] = event_no; /* Event number */
303 em_l1_event_buffer[em_l1_buffer_write++] = length-2; /* Value length - 0 equals no value */
304 em_l1_event_buffer[em_l1_buffer_write++] = value1; /* Data to be stored */
305 em_l1_event_buffer[em_l1_buffer_write++] = value2; /* Data to be stored */
306
307 return (em_l1_sem (length, em_l1_event_buffer)); /* Data is stored inside buffer, reset flag */
308 }
309
310 /*
311 +------------------------------------------------------------------------------
312 | Function : em_l1_sem_init
313 +------------------------------------------------------------------------------
314 | Description : Initialize the semaphor for alr event traces.
315 |
316 | Parameters : void
317 |
318 | Return : void
319 |
320 +------------------------------------------------------------------------------
321 */
322 GLOBAL void em_l1_sem_init (void)
323 {
324 sem_EM_L1 = vsi_s_open (VSI_CALLER "EM_L1_SEM",1);
325
326 if (sem_EM_L1 NEQ VSI_ERROR)
327 em_l1_sem_clear ();
328 else
329 SYST_TRACE ("D1:canīt open semaphore \"EM_D1_SEM\"");
330 }
331
332 /*
333 +------------------------------------------------------------------------------
334 | Function : em_l1_sem_exit
335 +------------------------------------------------------------------------------
336 | Description : Close the semaphor for alr event traces.
337 |
338 | Parameters : void
339 |
340 | Return : void
341 |
342 +------------------------------------------------------------------------------
343 */
344 GLOBAL void em_l1_sem_exit (void)
345 {
346 if (sem_EM_L1 NEQ VSI_ERROR)
347 vsi_s_close (VSI_CALLER sem_EM_L1);
348 }
349
350 /*
351 +------------------------------------------------------------------------------
352 | Function : em_l1_sem_clear
353 +------------------------------------------------------------------------------
354 | Description : Reset the index of the semaphor.
355 |
356 | Parameters : void
357 |
358 | Return : UBYTE
359 |
360 +------------------------------------------------------------------------------
361 */
362 LOCAL int em_l1_sem_clear (void)
363 {
364 ENTER_CRITICAL_SECTION (sem_EM_L1);
365 em_l1_sem_index = 0;
366 LEAVE_CRITICAL_SECTION (sem_EM_L1);
367
368 SYST_TRACE ("L1:em_l1_sem_index cleared");
369 return TRUE;
370 }
371
372 /*
373 +------------------------------------------------------------------------------
374 | Function : em_l1_sem_reset
375 +------------------------------------------------------------------------------
376 | Description : Clears the content of the semaphor, must called after em_l1_sem_read.
377 |
378 | Parameters : void
379 |
380 | Return : UBYTE
381 |
382 +------------------------------------------------------------------------------
383 */
384 GLOBAL int em_l1_sem_reset (void) /*lint -esym(765,em_l1_sem_reset) | external could be made static | used externally */
385 {
386 /* ENTER_CRITICAL_SECTION (sem_EM_L1); */
387 em_l1_sem_index = 0;
388 LEAVE_CRITICAL_SECTION (sem_EM_L1);
389
390 SYST_TRACE ("L1:em_l1_sem_index reseted");
391 return TRUE;
392 }
393
394 /*
395 +------------------------------------------------------------------------------
396 | Function : em_l1_sem_read
397 +------------------------------------------------------------------------------
398 | Description : Reads the content of the semaphor.
399 |
400 | Parameters : void
401 |
402 | Return : UBYTE
403 |
404 +------------------------------------------------------------------------------
405 */
406 GLOBAL int em_l1_sem_read (void) /*lint -esym(765,em_l1_sem_read) | external could be made static | used externally */
407 {
408 USHORT semCount;
409 TRACE_FUNCTION ("em_l1_sem_read()");
410
411 if (vsi_s_status (VSI_CALLER sem_EM_L1, &semCount) NEQ VSI_OK)
412 {
413 alr_em_semaphore_err();
414 return TRUE;
415 }
416 if (semCount EQ 0)
417 {
418 vsi_o_ttrace(VSI_CALLER TC_EVENT, "semCount = %d", semCount);
419 SYST_TRACE ("semCount EQ 0");
420 return TRUE;
421 }
422
423 ENTER_CRITICAL_SECTION (sem_EM_L1);
424 /*
425 * The l1/alr semaphor will be read by the engineering mode via aci,
426 * therefore the functions em_l1_sem_read and em_l1_sem_reset are defined
427 * as global. To ensure that during reading only aci has access to the
428 * semaphor the macro LEAVE_CRITICAL_SECTION is called after the read process
429 * toke place - in the em_l1_sem_resest function.
430 */
431 return TRUE;
432 }
433
434 /*
435 Return value TRUE/FALSE - TRUE keeps the event flag valid, FALSE indicates a successful flag handle
436 */
437 /*
438 +------------------------------------------------------------------------------
439 | Function : em_l1_sem
440 +------------------------------------------------------------------------------
441 | Description : Writes the data inside the semaphor.
442 |
443 | Parameters : void
444 |
445 | Return : UBYTE
446 |
447 +------------------------------------------------------------------------------
448 */
449 LOCAL UBYTE em_l1_sem (UBYTE length, UBYTE *data)
450 {
451 USHORT semCount;
452 UBYTE i;
453
454 TRACE_FUNCTION ("em_l1_sem()");
455
456
457 if (vsi_s_status (VSI_CALLER sem_EM_L1, &semCount) NEQ VSI_OK)
458 {
459 alr_em_semaphore_err();
460 return TRUE;
461 }
462 if (semCount EQ 0)
463 {
464 vsi_o_ttrace(VSI_CALLER TC_EVENT, "semCount = %d", semCount);
465 SYST_TRACE ("semCount EQ 0");
466 return TRUE;
467 }
468
469 /*
470 * buffer overflow protection
471 */
472 if ( (em_l1_sem_index + length) > EM_L1_SEM_SIZE )
473 {
474 TRACE_FUNCTION ("alr buffer full");
475 return FALSE;
476 }
477
478 ENTER_CRITICAL_SECTION(sem_EM_L1);
479
480 for (i=0; i<length; i++)
481 em_l1_sem_buffer[em_l1_sem_index++] = *(data++);
482
483
484 LEAVE_CRITICAL_SECTION (sem_EM_L1);
485 return FALSE; /* indicates that flag was handled */
486 } /* endfunc em_l1_sem */
487
488 /*
489 +------------------------------------------------------------------------------
490 | Function : alr_em_semaphore_err
491 +------------------------------------------------------------------------------
492 | Description : Semaphor error
493 |
494 |
495 | Parameters : void
496 |
497 | Return : void
498 |
499 +------------------------------------------------------------------------------
500 */
501 static void alr_em_semaphore_err (void)
502 {
503 static UCHAR out = 0;
504 if (!out)
505 {
506 out = 1;
507
508 /* Implements Measure#32: Row 56 */
509 TRACE_EVENT ("semaphore error");
510
511
512
513 }
514 }
515
516 /*
517 +------------------------------------------------------------------------------
518 | Function : alr_em_enter_critical_section
519 +------------------------------------------------------------------------------
520 | Description : Check on critical section entrance
521 |
522 |
523 | Parameters : Handle
524 |
525 | Return : -1 semaphore error
526 | 0 Ok.
527 |
528 +------------------------------------------------------------------------------
529 */
530
531 #if defined (NEW_FRAME)
532 static int alr_em_enter_critical_section (T_HANDLE sem)
533 #else
534 static int alr_em_enter_critical_section (T_VSI_SHANDLE sem)
535 #endif /* NEW_FRAME */
536 {
537 if (vsi_s_get (VSI_CALLER sem) NEQ VSI_OK)
538 {
539 alr_em_semaphore_err();
540 return -1;
541 }
542 else
543 {
544 return 0;
545 }
546 }/* endfunc rr_enter_critical_section */
547
548
549 /*
550 +------------------------------------------------------------------------------
551 | Function : alr_em_leave_critical_section
552 +------------------------------------------------------------------------------
553 | Description : Check on critical section exit
554 |
555 |
556 | Parameters : Handle
557 |
558 | Return : -1 semaphore error
559 | 0 Ok.
560 |
561 +------------------------------------------------------------------------------
562 */
563 #if defined (NEW_FRAME)
564 static int alr_em_leave_critical_section (T_HANDLE sem)
565 #else
566 static int alr_em_leave_critical_section (T_VSI_SHANDLE sem)
567 #endif /* NEW_FRAME */
568 {
569 if (vsi_s_release (VSI_CALLER sem) NEQ VSI_OK)
570 {
571 alr_em_semaphore_err();
572 return -1;
573 }
574 else
575 {
576 return 0;
577 }
578 }/* endfunc rr_leave_critical_section */
579
580 /*
581 +------------------------------------------------------------------------------
582 | Function : alr_em_error_cause
583 +------------------------------------------------------------------------------
584 | Description : Check the error cause and store it in the event buffer
585 |
586 | Parameters : Cause
587 |
588 | Return : None
589 |
590 +------------------------------------------------------------------------------
591 */
592
593 GLOBAL void alr_em_error_cause (UBYTE cause, USHORT arfcn)
594
595 {
596 switch(cause)
597 {
598 case CS_BCCH_READ_ERROR:
599 { /* Power measurement request */
600 ALR_EM_BCCH_READ_ERROR;
601 break;
602 }
603 case CS_DOWN_LINK_FAIL:
604 { /* Downlink signalling failure */
605 ALR_EM_DOWNLINK_FAILURE;
606 break;
607 }
608 case CS_NO_BCCH_AVAIL:
609 { /* neighbourcell BCCH not available */
610 ALR_EM_NEIGHBOURCELL_BCCH(EM_NOT_AVAIL);
611 break;
612 }
613 }/*switch*/
614 }/* alr_em_error_cause */
615
616
617 /*
618 +------------------------------------------------------------------------------
619 | Function : alr_em_first_event_check()
620 +------------------------------------------------------------------------------
621 | Description : Checks if first EM-Event ocured
622 |
623 | Parameters : None
624 |
625 | Return : None
626 |
627 +------------------------------------------------------------------------------
628 */
629
630 /*
631 ACI is informed about the first event trace, used for later data processing.
632 */
633 LOCAL void alr_em_first_event_check (void)
634
635 {
636 TRACE_FUNCTION("alr_em_first_event_check()");
637 if(em_alr_trace_occured EQ 0)
638 {
639 PALLOC(em_notification, EM_DATA_IND);
640 em_notification->entity = EM_L1;
641 PSENDX(MMI, em_notification);
642 em_alr_trace_occured++;
643 }
644 }/* alr_em_first_event_check */
645
646
647
648 #endif /* FF_EM_MODE */
649
650
651
652 #endif /* ALR_EM_C */