comparison g23m-gsm/dl/dl_com.c @ 0:75a11d740a02

initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 09 Jun 2016 00:02:41 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:75a11d740a02
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 Modul defines the common functions
18 | for the component DL of the mobile station.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef DL_COM_C
23 #define DL_COM_C
24
25 #include "config.h"
26 #include "fixedconf.h"
27 #include "condat-features.h"
28
29 #define ENTITY_DL
30
31 /*==== INCLUDES ===================================================*/
32 #include "typedefs.h"
33 #include <string.h>
34 #include "vsi.h"
35 #if !defined(DL_2TO1)
36 //#include "p_8010_147_l1_include.h"
37 #endif /* DL_2TO1 */
38 #include "pconst.cdg"
39 #include "custom.h"
40 #include "gsm.h"
41 #include "mon_dl.h"
42 #include "prim.h"
43 #include "pei.h"
44 #include "tok.h"
45 #include "ccdapi.h"
46 #include "dl.h"
47 #include "dl_trc.h"
48 #include "dl_em.h"
49
50 /*==== TEST TRACE ===================================================*/
51 #define TEST_ENTITY_DL
52
53 /*==== EXPORT =====================================================*/
54
55 /*==== PRIVAT =====================================================*/
56 LOCAL void com_build_frame (
57 UBYTE ch_type,
58 UBYTE type,
59 UBYTE sapi,
60 UBYTE cr,
61 UBYTE ns,
62 UBYTE nr,
63 UBYTE p_bit,
64 UBYTE length,
65 UBYTE m_bit,
66 UBYTE * pInfoBuffer,
67 UBYTE InfoOffset);
68
69 /*==== VARIABLES ==================================================*/
70
71 /*==== FUNCTIONS ==================================================*/
72
73 /*
74 +------------------------------------------------------------------------------
75 | Function : com_free_pointer
76 +------------------------------------------------------------------------------
77 | Description : frees the pointer given by parameter
78 +------------------------------------------------------------------------------
79 */
80 GLOBAL void com_free_pointer (void * pointer)
81 {
82 GET_INSTANCE_DATA;
83 TRACE_EVENT_WIN_P1 ("com_free_pointer(,p=%08x)", pointer);
84
85 #if defined(INVOKE_SIGNAL)
86 if (dl_data->interrupt_context)
87 {
88 sig_invoke_com_free_pointer (pointer);
89 return;
90 }
91 #endif /* INVOKE_SIGNAL */
92
93 TRACE_ASSERT(pointer);
94 MY_PFREE (pointer);
95 }
96
97 GLOBAL void com_free_queue_buffer (T_QUEUE * queue, USHORT index)
98 {
99 T_DL_DATA_REQ **pp;
100
101 switch (index)
102 {
103 default:
104 if (index <= INDEX_MAX_STORE_BUFFER)
105 pp = &queue->store_buffer[index];
106 else
107 pp = NULL;
108 break;
109 case INDEX_SENDING_BUFFER:
110 pp = &queue->sending_buffer;
111 break;
112 case INDEX_SWITCH_BUFFER:
113 pp = &queue->switch_buffer;
114 break;
115 }
116 if (pp AND *pp)
117 {
118 COM_FREE_POINTER (*pp);
119 *pp = NULL;
120 }
121 }
122
123 /*
124 +--------------------------------------------------------------------+
125 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
126 | STATE : code ROUTINE : com_clear_queue |
127 +--------------------------------------------------------------------+
128
129 PURPOSE : Clearing a DL queue.
130
131 */
132
133 GLOBAL void com_clear_queue (UBYTE sapi)
134 {
135 GET_INSTANCE_DATA;
136 USHORT i;
137 T_QUEUE *queue;
138 TRACE_FUNCTION ("com_clear_queue()");
139
140 if (sapi EQ PS_SAPI_0)
141 {
142 queue = &dl_data->dcch0_queue;
143 }
144 else
145 {
146 queue = &dl_data->dcch3_queue;
147 }
148
149 for (i=0;i<MAX_QUEUED_MESSAGES;i++)
150 if (queue->store_buffer [i] NEQ NULL)
151 {
152 COM_FREE_QUEUE_BUFFER (queue, i);
153 }
154
155 if (queue->sending_buffer NEQ NULL)
156 {
157 COM_FREE_QUEUE_BUFFER (queue, INDEX_SENDING_BUFFER);
158 }
159
160 if (queue->switch_buffer NEQ NULL)
161 {
162 COM_FREE_QUEUE_BUFFER (queue, INDEX_SWITCH_BUFFER);
163 }
164 queue->act_length = queue->act_offset = 0;
165 queue->no_of_stored_messages = 0;
166 memset (&queue->transmit_buffer, 0, sizeof (T_FRAME));
167 }
168
169 /*
170 +--------------------------------------------------------------------+
171 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
172 | STATE : code ROUTINE : com_restore_queue |
173 +--------------------------------------------------------------------+
174
175 PURPOSE : Restoring a DL queue. If a new connection shall be
176 established, the message (ASSIGNMENT or HANDOVER COMPLETE)
177 is transmitted first. So the message is stored in the
178 switch buffer. A previously not complete send message will
179 be put back into the storing buffer.
180
181 */
182
183 GLOBAL void com_restore_queue (UBYTE sapi, T_DL_DATA_REQ* est_req)
184 {
185 GET_INSTANCE_DATA;
186 T_QUEUE *queue = sapi EQ PS_SAPI_0 ? &dl_data->dcch0_queue:&dl_data->dcch3_queue;
187
188 TRACE_FUNCTION ("com_restore_queue()");
189
190 if (queue->switch_buffer NEQ NULL)
191 {
192 TRACE_EVENT_WIN ("free old switch_buffer");
193 COM_FREE_QUEUE_BUFFER (queue, INDEX_SWITCH_BUFFER);
194 }
195
196 if (est_req AND est_req->sdu.l_buf)
197 {
198 PPASS (est_req, data_req, DL_DATA_REQ);
199 queue->switch_buffer = data_req; /* only valid sdu */
200
201 TRACE_EVENT_WIN_P2 ("new fill of switch_buffer:%p l=%u",
202 data_req, est_req->sdu.l_buf>>3);
203 }
204
205 if (queue->sending_buffer NEQ NULL)
206 {
207 TRACE_EVENT_WIN ("restore sending_buffer");
208 queue->act_length = queue->sending_buffer->sdu.l_buf;
209 queue->act_offset = queue->sending_buffer->sdu.o_buf;
210 }
211 TRACE_EVENT_WIN ("delete transmit_buffer");
212 memset (&queue->transmit_buffer, 0, sizeof (T_FRAME));
213 }
214
215 /*
216 +--------------------------------------------------------------------+
217 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
218 | STATE : code ROUTINE : com_recover_queue |
219 +--------------------------------------------------------------------+
220
221 PURPOSE : Recover a DL queue after a Reject condition.
222
223 */
224
225 GLOBAL void com_recover_queue (UBYTE sapi)
226 {
227 GET_INSTANCE_DATA;
228 T_QUEUE *queue = sapi EQ PS_SAPI_0 ? &dl_data->dcch0_queue:&dl_data->dcch3_queue;
229
230 TRACE_FUNCTION ("com_recover_queue()");
231
232 if (queue->sending_buffer NEQ NULL)
233 {
234 if(queue->act_length NEQ 0) /* For last buf, act_length is set to 0 */
235 { /* and the act_offset is not modified */
236 queue->act_offset -= queue->transmit_buffer.l_buf;
237 }
238 queue->act_length += queue->transmit_buffer.l_buf;
239 }
240 memset (&queue->transmit_buffer, 0, sizeof (T_FRAME));
241 }
242
243 /*
244 +--------------------------------------------------------------------+
245 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
246 | STATE : code ROUTINE : com_read_queue |
247 +--------------------------------------------------------------------+
248
249 PURPOSE : Reading the next segment of a message from a DL queue.
250 If a message in the switch buffer is stored, this message
251 is used. If a message is stored in the sending buffer which
252 is not send completely the next segment is copied to the
253 transmit buffer. Else the next sending buffer is copied from
254 the store buffer of the queue. The first segment of this
255 message is copied to the transfer buffer.
256
257 */
258
259 GLOBAL void com_read_queue (UBYTE ch_type, UBYTE sapi,
260 UBYTE * m_bit)
261 {
262 GET_INSTANCE_DATA;
263 USHORT i;
264 USHORT length, bit_length;
265 T_DL_DATA_REQ * dl_data_req;
266 T_QUEUE *queue = sapi EQ PS_SAPI_0 ? &dl_data->dcch0_queue : &dl_data->dcch3_queue;
267
268 TRACE_FUNCTION ("com_read_queue()");
269 TRACE_EVENT_WIN_P1 ("read sapi_%u_queue", sapi);
270
271 switch (ch_type)
272 {
273 case L2_CHANNEL_SDCCH:
274 length = N201_SDCCH;
275 break;
276
277 case L2_CHANNEL_SACCH:
278 length = N201_SACCH;
279 break;
280
281 case L2_CHANNEL_FACCH_F:
282 case L2_CHANNEL_FACCH_H:
283 length = N201_FACCH;
284 break;
285
286 default:
287 length = 0;
288 bit_length = 0;
289 break;
290 }
291 bit_length = length << 3;
292
293 if (queue->switch_buffer NEQ NULL)
294 {
295 T_DL_DATA_REQ *switch_buffer = queue->switch_buffer;
296
297 TRACE_EVENT_WIN_P2 ("fill transmit_buffer with bytes %u-%u of switch_buffer, no bytes left",
298 (switch_buffer->sdu.o_buf>>3),
299 ((switch_buffer->sdu.o_buf+switch_buffer->sdu.l_buf)>>3)-1);
300
301 queue->m_bit = * m_bit = 0;
302 queue->transmit_buffer.o_buf = 24;
303 queue->transmit_buffer.l_buf = switch_buffer->sdu.l_buf;
304 for (i=0;i<(switch_buffer->sdu.l_buf>>3);i++)
305 queue->transmit_buffer.buf[i+3] =
306 switch_buffer->sdu.buf[i+(switch_buffer->sdu.o_buf>>3)];
307
308 /*
309 should be freed first after acknowledgement!
310 COM_FREE_QUEUE_BUFFER (dl_data, queue, INDEX_SWITCH_BUFFER);
311 */
312 return;
313 }
314 else
315 {
316 if (queue->act_length EQ 0)
317 {
318 if (queue->sending_buffer NEQ NULL)
319 {
320 COM_FREE_QUEUE_BUFFER (queue, INDEX_SENDING_BUFFER);
321 }
322 queue->sending_buffer = queue->store_buffer[0];
323 queue->act_offset = queue->sending_buffer->sdu.o_buf;
324 queue->act_length = queue->sending_buffer->sdu.l_buf;
325 TRACE_EVENT_WIN_P2 ("fill sending_buffer with bytes %u-%u of store_buffer[0]",
326 (queue->sending_buffer->sdu.o_buf>>3),
327 ((queue->sending_buffer->sdu.o_buf+queue->sending_buffer->sdu.l_buf)>>3)-1);
328
329 for (i=0;i<MAX_QUEUED_MESSAGES-1;i++)
330 queue->store_buffer[i] = queue->store_buffer[i+1];
331 queue->no_of_stored_messages--;
332
333 TRACE_EVENT_WIN_P1 ("left no_of_stored_messages=%u", queue->no_of_stored_messages);
334 }
335 dl_data_req = queue->sending_buffer;
336 }
337
338
339 if (queue->act_length > bit_length)
340 { /*
341 * lint Info 702: Shift right of signed quantity:
342 * not possible because of the compare one line before
343 */
344 TRACE_EVENT_WIN_P3 ("fill transmit_buffer with bytes %u-%u of sending_buffer, %u bytes left",
345 queue->act_offset>>3, (queue->act_offset>>3)+length-1,
346 (queue->act_length-bit_length)>>3);
347
348 queue->m_bit = * m_bit = 1;
349 queue->transmit_buffer.o_buf = 24;
350 queue->transmit_buffer.l_buf = bit_length;
351 for (i=0;i<length;i++)
352 queue->transmit_buffer.buf[i+3] =
353 dl_data_req->sdu.buf[i+(queue->act_offset>>3)];
354 queue->act_offset += bit_length;
355 queue->act_length -= bit_length;
356 }
357 else
358 {
359 TRACE_EVENT_WIN_P2 ("fill transmit_buffer with bytes %u-%u of sending_buffer, no bytes left",
360 queue->act_offset>>3, ((queue->act_offset+queue->act_length)>>3)-1);
361
362 queue->m_bit = * m_bit = 0;
363 queue->transmit_buffer.o_buf = 24;
364 queue->transmit_buffer.l_buf = queue->act_length;
365 for (i=0;i<(queue->act_length>>3);i++)
366 queue->transmit_buffer.buf[i+3] =
367 dl_data_req->sdu.buf[i+(queue->act_offset>>3)];
368 queue->act_length = 0;
369 }
370 }
371
372 /*
373 +--------------------------------------------------------------------+
374 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
375 | STATE : code ROUTINE : com_store_queue |
376 +--------------------------------------------------------------------+
377
378 PURPOSE : Storing a message into the queue.
379
380 */
381
382 GLOBAL void com_store_queue (UBYTE sapi, T_DL_DATA_REQ * data_req)
383 {
384 GET_INSTANCE_DATA;
385 T_QUEUE * queue;
386
387 TRACE_FUNCTION ("com_store_queue()");
388
389 if (sapi EQ PS_SAPI_0)
390 {
391 queue = &dl_data->dcch0_queue;
392 }
393 else
394 {
395 queue = &dl_data->dcch3_queue;
396 }
397
398 if (queue->no_of_stored_messages < MAX_QUEUED_MESSAGES)
399 {
400 queue->store_buffer[queue->no_of_stored_messages++] = data_req;
401 TRACE_EVENT_WIN_P3 ("sapi_%u_queue: add entry with %u bytes, no_of_stored_messages=%u",
402 sapi, data_req->sdu.l_buf>>3, queue->no_of_stored_messages);
403 }
404 else
405 {
406 COM_FREE_POINTER (data_req);
407 TRACE_EVENT_WIN_P1 ("sapi_%u_queue overflowed", sapi);
408 }
409 }
410
411 /*
412 +------------------------------------------------------------------------------+
413 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
414 | STATE : code ROUTINE : com_queue_awaiting_transmission |
415 +------------------------------------------------------------------------------+
416
417 PURPOSE : The function checks whether any segment has to sended.
418 Function returns TRUE if a frame/segment is awaiting transmission.
419 Function returns FALSE if not.
420
421 */
422
423 GLOBAL BOOL com_queue_awaiting_transmission (UBYTE sapi)
424 {
425 GET_INSTANCE_DATA;
426 T_QUEUE * queue;
427 BOOL ret;
428
429 TRACE_EVENT_WIN_P1 ("com_queue_awaiting_transmission(SAPI=%u)", sapi);
430
431 queue = (sapi EQ PS_SAPI_0) ? &dl_data->dcch0_queue : &dl_data->dcch3_queue;
432 if (sapi EQ PS_SAPI_0)
433 {
434 queue = &dl_data->dcch0_queue;
435 }
436 else
437 {
438 queue = &dl_data->dcch3_queue;
439 }
440 if (queue->switch_buffer NEQ NULL)
441 {
442 TRACE_EVENT_WIN_P1 ("sapi_%u_queue: switch_buffer is awaiting", sapi);
443 ret = TRUE;
444 }
445 else
446 {
447 if (queue->act_length EQ 0)
448 {
449 ret = queue->no_of_stored_messages NEQ 0;
450 if (ret)
451 {
452 TRACE_EVENT_WIN_P2 ("sapi_%u_queue: store_buffer is awaiting (no_of_stored_messages=%u)",
453 sapi, queue->no_of_stored_messages);
454 }
455 }
456 else
457 {
458 TRACE_EVENT_WIN_P2 ("sapi_%u_queue: transmit_buffer is awaiting (%u bytes)",
459 sapi, queue->act_length);
460 ret = TRUE;
461 }
462 }
463
464 return ret;
465 }
466
467 /*
468 +--------------------------------------------------------------------+
469 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
470 | STATE : code ROUTINE : com_leave_dedicated |
471 +--------------------------------------------------------------------+
472
473 PURPOSE : Leave dedicated mode.
474
475 */
476
477 GLOBAL void com_leave_dedicated (UBYTE ch_type)
478 {
479 GET_INSTANCE_DATA;
480 dl_data->RR_dedicated = FALSE; /* RR is leaving the dedicated mode */
481 DL_OFFLINE_TRACE (TRACE_DL_EVENT, TRACE_CH_UNKNOWN, ch_type, "RR_dedicated:=FALSE");
482 }
483
484 /*
485 +-----------------------------------------------------------------------------+
486 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
487 | STATE : code ROUTINE : possible_reset_dcch0_ch_type |
488 +-----------------------------------------------------------------------------+
489
490 PURPOSE : Reset dedicated channel.
491
492 */
493 GLOBAL void possible_reset_dcch0_ch_type (void)
494 {
495 GET_INSTANCE_DATA;
496 if (
497 #if defined(DELAYED_SABM)
498 (dl_data->dcch0_sabm_flag NEQ NOT_PRESENT_8BIT) AND
499 #endif /* DELAYED_SABM */
500 #if defined(DELAYED_RELEASE_IND)
501 (dl_data->release_ind_ch_type NEQ NOT_PRESENT_8BIT) AND
502 #endif /* DELAYED_RELEASE_IND */
503 (dl_data->state[C_DCCH0] <= STATE_IDLE_DL) AND
504 (dl_data->cch[C_DCCH0].vtx EQ EMPTY_CMD))
505 {
506 TRACE_EVENT_WIN_P1 ("reset dcch0_ch_type=%s ->0", CH_TYPE_NAME[dl_data->dcch0_ch_type]);
507 dl_data->dcch0_ch_type = 0;
508 }
509 }
510
511 /*
512 +--------------------------------------------------------------------+
513 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
514 | STATE : code ROUTINE : com_compare_L3_msg |
515 +--------------------------------------------------------------------+
516
517 PURPOSE : The function compares two layer 3 messages.
518
519
520 */
521
522 GLOBAL UBYTE com_compare_L3_msg (T_DL_DATA_REQ * data_ind1, UBYTE * data_ind2)
523 {
524 USHORT length1;
525 USHORT length2;
526 USHORT pos1;
527 USHORT pos2;
528 USHORT i;
529
530 TRACE_FUNCTION ("com_compare_L3_msg()");
531
532 /*
533 * Calculates Length of SABM and UA layer 3 message
534 */
535 length1 = data_ind1->sdu.l_buf>>3; /* length of l3 msg inside SABM frame */
536 length2 = ((data_ind2[2] & 0xFC)>>2); /* length of l3 msg inside UA frame */
537
538 if (length1 NEQ length2)
539 return FALSE;
540
541 pos1 = data_ind1->sdu.o_buf >> 3;
542 pos2 = 3;
543
544
545 for (i=0; i<length1; i++)
546 {
547 if (data_ind1->sdu.buf[i+pos1] NEQ data_ind2[i+pos2])
548 {
549 #if defined(DL_TRACE_ENABLED)
550 UBYTE sapi = data_ind1->sapi;
551 UBYTE trace_channel = TRACE_CH_UNKNOWN;
552 switch (data_ind1->ch_type)
553 {
554 case L2_CHANNEL_SDCCH:
555 if (sapi EQ PS_SAPI_0)
556 trace_channel = C_DCCH0;
557 else if (sapi EQ PS_SAPI_3)
558 trace_channel = C_DCCH3;
559 break;
560 case L2_CHANNEL_FACCH_F:
561 case L2_CHANNEL_FACCH_H:
562 trace_channel = C_DCCH0;
563 break;
564 default:
565 break;
566 }/* endswitch chan */
567 DL_OFFLINE_TRACE(TRACE_DL_EVENT, trace_channel, data_ind1->ch_type, "UA doesn´t match");
568 #endif /* DL_TRACE_ENABLED */
569 return FALSE;
570 }
571 }
572 return TRUE;
573 }
574
575 /*
576 +--------------------------------------------------------------------+
577 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
578 | STATE : code ROUTINE : com_concatenate |
579 +--------------------------------------------------------------------+
580
581 PURPOSE : Concenate an imcoming segment.
582
583 */
584
585 GLOBAL void com_concatenate (T_DL_DATA_IND ** in_msg,
586 UBYTE * new_data_in)
587 {
588 GET_INSTANCE_DATA;
589 USHORT end_pos;
590 USHORT length;
591 USHORT start_pos;
592 #define L2_HEADER_BYTESIZE 3
593
594 TRACE_FUNCTION ("com_concatenate()");
595
596 #if defined(INVOKE_SIGNAL)
597 if (dl_data->interrupt_context)
598 {
599 sig_invoke_com_concatenate (in_msg, new_data_in);
600 return;
601 }
602 #endif /* INVOKE_SIGNAL */
603
604 length = new_data_in[2] >> 2;
605
606 if (*in_msg EQ NULL)
607 {
608 /*
609 * Nothing stored yet
610 */
611 USHORT len_in_bits = (length + L2_HEADER_BYTESIZE) << 3;
612 PALLOC_SDU (first_data, DL_DATA_IND, len_in_bits );
613
614 first_data->sdu.l_buf = length << 3; /* = length * BITS_PER_BYTE */
615 first_data->sdu.o_buf = L2_HEADER_BYTESIZE << 3;/* = L2_HEADER_BYTESIZE * BITS_PER_BYTE */
616 /*lint -e419 (Warning -- Apparent data overrun) */
617 memset (&first_data->sdu.buf[0], 0, L2_HEADER_BYTESIZE);
618 /*lint +e419 (Warning -- Apparent data overrun) */
619 /*lint -e416 (Warning -- creation of out-of-bounds pointer) */
620 memcpy (&first_data->sdu.buf[L2_HEADER_BYTESIZE],
621 &new_data_in[L2_HEADER_BYTESIZE],
622 length);
623 /*lint +e416 (Warning -- creation of out-of-bounds pointer) */
624 *in_msg = first_data;
625 }
626 else
627 {
628 T_DL_DATA_IND *previous_data = *in_msg;
629
630 start_pos = previous_data->sdu.l_buf + previous_data->sdu.o_buf;
631 end_pos = (length << 3) + start_pos;
632 {
633 PALLOC_SDU (entire_data, DL_DATA_IND, end_pos );
634
635 /*lint -e415 (Warning -- access of out-of-bounds pointer) */
636 memcpy (entire_data->sdu.buf, previous_data->sdu.buf, start_pos >> 3);
637 memcpy (&entire_data->sdu.buf[start_pos >> 3],
638 &new_data_in[L2_HEADER_BYTESIZE],
639 length);
640 /*lint +e415 (Warning -- access of out-of-bounds pointer) */
641
642 entire_data->sdu.l_buf = previous_data->sdu.l_buf + (length << 3);
643 entire_data->sdu.o_buf = previous_data->sdu.o_buf;
644
645 COM_FREE_POINTER (*in_msg);
646 *in_msg = entire_data;
647 }
648 }
649 }
650
651 /*
652 +--------------------------------------------------------------------+
653 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
654 | STATE : code ROUTINE : com_check_nr |
655 +--------------------------------------------------------------------+
656
657 PURPOSE : Check the receive number.
658
659 */
660
661 GLOBAL UBYTE com_check_nr (UBYTE va, UBYTE vs, UBYTE nr)
662 {
663 BYTE a,b;
664
665 TRACE_FUNCTION ("com_check_nr()");
666 /*
667 * under GSM 4.06 subclause 3.5.2.3:
668 * nr is valid, if and only if ((nr-va) mod 8) <= ((vs-va) mod 8)
669 */
670 a = (nr+8-va) & 7;
671 b = (vs+8-va) & 7;
672
673 return (a <= b);
674 }
675
676 /*
677 +--------------------------------------------------------------------+
678 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
679 | STATE : code ROUTINE : com_prepare_DISC |
680 +--------------------------------------------------------------------+
681
682 PURPOSE : Prepares a DISC command.
683
684 */
685
686 GLOBAL void com_prepare_DISC (UBYTE channel, UBYTE sapi)
687 {
688 GET_INSTANCE_DATA;
689 T_CCH *pcch = &dl_data->cch[channel];
690
691 pcch->vtx = DISC_CMD;
692 pcch->time_flag = TRUE;
693 pcch->T200_counter = 0;
694 pcch->rc = 0;
695 set_channel_state (channel, STATE_AWAITING_RELEASE);
696 TRACE_EVENT_WIN_P3 ("RELEASE_REQ: %s SAPI=%u vtx=%s", CH_TYPE_NAME[pcch->ch_type],
697 sapi, VTX_NAME[pcch->vtx]);
698 }
699
700 /*
701 +--------------------------------------------------------------------+
702 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
703 | STATE : code ROUTINE : com_build_UA_response |
704 +--------------------------------------------------------------------+
705
706 PURPOSE : Build an UA response.
707
708 */
709
710 GLOBAL void com_build_UA_response (UBYTE ch_type, UBYTE sapi, UBYTE f_bit)
711 {
712 TRACE_FUNCTION ("com_build_UA_response()");
713 com_build_frame (ch_type, UA_FRAME, sapi, MS2BS_RSP, 0, 0, f_bit, 0, 0, NULL, 0);
714 }
715
716 /*
717 +--------------------------------------------------------------------+
718 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
719 | STATE : code ROUTINE : com_build_RR_response |
720 +--------------------------------------------------------------------+
721
722 PURPOSE : Build an RR response.
723
724 */
725
726 GLOBAL void com_build_RR_response (UBYTE ch_type,
727 UBYTE sapi, UBYTE nr, UBYTE f_bit)
728 {
729 TRACE_FUNCTION ("com_build_RR_response()");
730 com_build_frame (ch_type, RR_FRAME, sapi, MS2BS_RSP, 0, nr, f_bit, 0, 0, NULL, 0);
731 }
732
733 #if 0
734 /*
735 +--------------------------------------------------------------------+
736 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
737 | STATE : code ROUTINE : com_build_RR_command |
738 +--------------------------------------------------------------------+
739
740 PURPOSE : Build an RR command.
741
742 */
743
744 GLOBAL void com_build_RR_command (T_DL_DATA_STORE * dl_data, UBYTE ch_type,
745 UBYTE sapi, UBYTE nr, UBYTE p_bit)
746 {
747 TRACE_FUNCTION ("com_build_RR_command()");
748 com_build_frame (dl_data, ch_type, RR_FRAME, sapi, MS2BS_CMD, 0, nr, p_bit, 0, 0, NULL, 0);
749 }
750 #endif /* 0 */
751 /*
752 +--------------------------------------------------------------------+
753 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
754 | STATE : code ROUTINE : com_build_REJ_response|
755 +--------------------------------------------------------------------+
756
757 PURPOSE : Build an REJ response.
758
759 */
760
761 GLOBAL void com_build_REJ_response (UBYTE ch_type,
762 UBYTE sapi, UBYTE nr, UBYTE f_bit)
763 {
764 TRACE_FUNCTION ("com_build_REJ_response()");
765 com_build_frame (ch_type, REJ_FRAME, sapi, MS2BS_RSP, 0, nr, f_bit, 0, 0, NULL, 0);
766 }
767
768 /*
769 +--------------------------------------------------------------------+
770 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
771 | STATE : code ROUTINE : com_build_DISC_command |
772 +--------------------------------------------------------------------+
773
774 PURPOSE : Build a DISC command.
775
776 */
777
778 GLOBAL void com_build_DISC_command (UBYTE ch_type,
779 UBYTE sapi, UBYTE p_bit)
780 {
781 TRACE_FUNCTION ("com_build_DISC_command()");
782 com_build_frame (ch_type, DISC_FRAME, sapi, MS2BS_CMD, 0, 0, p_bit, 0, 0, NULL, 0);
783 }
784
785 /*
786 +--------------------------------------------------------------------+
787 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
788 | STATE : code ROUTINE : com_build_SABM |
789 +--------------------------------------------------------------------+
790
791 PURPOSE : Build a SABM command with or without Layer 3 message.
792
793 */
794
795 GLOBAL void com_build_SABM (UBYTE ch_type,
796 UBYTE sapi, BOOL contention_resultion)
797 {
798 GET_INSTANCE_DATA;
799 T_QUEUE *queue = &dl_data->dcch0_queue;
800 TRACE_FUNCTION ("com_build_SABM()");
801 TRACE_EVENT_WIN_P3 ("com_build_SABM %s SAPI=%u %s", CH_TYPE_NAME[ch_type], sapi,
802 (contention_resultion AND queue->switch_buffer) ? "+L3" : "");
803
804 if (contention_resultion AND queue->switch_buffer)
805 {
806 com_build_frame (ch_type, SABM_FRAME, sapi, MS2BS_CMD, 0, 0, 1,
807 (UBYTE)(queue->switch_buffer->sdu.l_buf >> 3), 0,
808 queue->switch_buffer->sdu.buf, (UBYTE)(queue->switch_buffer->sdu.o_buf >> 3));
809 }
810 else
811 {
812 com_build_frame (ch_type, SABM_FRAME, sapi, MS2BS_CMD, 0, 0, 1, 0, 0, NULL, 0);
813 }
814 }
815
816 /*
817 +--------------------------------------------------------------------+
818 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
819 | STATE : code ROUTINE : com_build_DM_response |
820 +--------------------------------------------------------------------+
821
822 PURPOSE : Build an DM response.
823
824 */
825
826 GLOBAL void com_build_DM_response (UBYTE ch_type,
827 UBYTE sapi, UBYTE f_bit)
828 {
829 TRACE_FUNCTION ("com_build_DM_response()");
830 com_build_frame (ch_type, DM_FRAME, sapi, MS2BS_RSP, 0, 0, f_bit, 0, 0, NULL, 0);
831 }
832
833
834 /*
835 +--------------------------------------------------------------------+
836 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
837 | STATE : code ROUTINE : com_build_I_command |
838 +--------------------------------------------------------------------+
839
840 PURPOSE : Build an I command.
841
842 */
843
844 GLOBAL void com_build_I_command (UBYTE ch_type,
845 UBYTE sapi, UBYTE ns, UBYTE nr, UBYTE p_bit,UBYTE m_bit, T_QUEUE * queue)
846 {
847 TRACE_FUNCTION ("com_build_I_command()");
848 com_build_frame (ch_type, I_FRAME, sapi, MS2BS_CMD, ns, nr, p_bit,
849 (UBYTE)(queue->transmit_buffer.l_buf >> 3), m_bit,
850 queue->transmit_buffer.buf, 0);
851 }
852
853 /*
854 +--------------------------------------------------------------------+
855 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
856 | STATE : code ROUTINE : com_build_UI_command |
857 +--------------------------------------------------------------------+
858
859 PURPOSE : Build an UI command.
860
861 */
862
863 GLOBAL void com_build_UI_command (UBYTE ch_type,
864 UBYTE sapi, const T_FRAME * buffer)
865 {
866 TRACE_FUNCTION ("com_build_UI_command()");
867 com_build_frame (ch_type, UI_FRAME, sapi, MS2BS_CMD, 0, 0, 0,
868 (UBYTE)(buffer->l_buf >> 3), 0, (UBYTE*)buffer->buf, (UBYTE)(buffer->o_buf >> 3));
869 }
870
871 /*
872 +--------------------------------------------------------------------+
873 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
874 | STATE : code ROUTINE : com_build_UI_Bter |
875 +--------------------------------------------------------------------+
876
877 PURPOSE : Build an UI frame in Bter format.
878
879 */
880
881 GLOBAL void com_build_UI_Bter (UBYTE ch_type)
882 {
883 GET_INSTANCE_DATA;
884 unsigned off = dl_data->rr_short_pd_buffer.o_buf>>3;
885 unsigned len = dl_data->rr_short_pd_buffer.l_buf>>3;
886 unsigned foff, maxlen;
887
888 if (ch_type EQ L2_CHANNEL_SACCH)
889 {
890 maxlen = DL_N201_SACCH_Bter;
891 foff = 2;
892 #ifndef DL_2TO1
893 dl_data->l2_frame.A[0] = dl_data->l2_frame.A[1] = 0; /* place holder for L1 header */
894 #else
895 dl_data->l2_frame.frame_array[0] = dl_data->l2_frame.frame_array[1] = 0; /* place holder for L1 header */
896 #endif
897
898 }
899 else
900 {
901 foff = 0;
902 maxlen = DL_N201_DCCH_Bter;
903 }
904
905 if (len > maxlen)
906 len = maxlen;
907 /*
908 * LINT Warning 662: Possible creation of out-of-bounds pointer ... and
909 * LINT Warning 669: Possible data overrun for function 'memset ...
910 * can be ignored, because of the right alignment between foff and maxlen.
911 */
912 /*lint -e662 -e669 Possible creation of out-of-bounds pointer or Possible data overrun*/
913 #ifndef DL_2TO1
914 memcpy (&dl_data->l2_frame.A[foff], dl_data->rr_short_pd_buffer.buf+off, len);
915 memset (&dl_data->l2_frame.A[foff+len], 0x2b, maxlen-len);
916 #else
917 memcpy (&dl_data->l2_frame.frame_array[foff], dl_data->rr_short_pd_buffer.buf+off, len);
918 memset (&dl_data->l2_frame.frame_array[foff+len], 0x2b, maxlen-len);
919 #endif
920 /* lint +e662 +e669 Possible creation of out-of-bounds pointer or Possible data overrun */
921 /* mark message as handled */
922 dl_data->rr_short_pd_buffer.l_buf = 0;
923 }
924
925 /*
926 +--------------------------------------------------------------------+
927 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
928 | STATE : code ROUTINE : com_build_frame |
929 +--------------------------------------------------------------------+
930
931 PURPOSE : Builds any frame.
932
933 */
934 LOCAL void com_build_frame (UBYTE ch_type,
935 UBYTE type, UBYTE sapi, UBYTE cr, UBYTE ns,
936 UBYTE nr, UBYTE p_bit, UBYTE length, UBYTE m_bit,
937 UBYTE* pInfoBuffer, UBYTE InfoOffset)
938 {
939 GET_INSTANCE_DATA;
940 UBYTE offset;
941 UBYTE maxlength;
942 #ifndef DL_2TO1
943 UBYTE *pOutFrame = dl_data->l2_frame.A;
944 #else
945 UBYTE *pOutFrame = dl_data->l2_frame.frame_array;
946 #endif /* DL_2TO1*/
947 #define SPARE 0
948 #define LPD 0
949 #define EA 1
950 #define EL 1
951
952 if (ch_type EQ L2_CHANNEL_SACCH)
953 {
954 offset = 2;
955 maxlength = DL_N201_SACCH_A_B;
956 pOutFrame[0] = pOutFrame[1] = 0; /* reset layer 1 header */
957 }
958 else
959 {
960 offset = 0;
961 maxlength = DL_N201_DCCH_A_B;
962 }
963
964 if (length > maxlength)
965 {
966 TRACE_EVENT_P1 ("Error: framelength to big %d", length);
967 length = maxlength; /* for safety's sake */
968 }
969
970 /*
971 * set header bytes (bit 8 7 6 5 4 3 2 1)
972 * address field | | | | | | |
973 * Spare --LPD- ----SAPI--- C/R EA
974 */
975 pOutFrame[offset] = (SPARE << 7) | (LPD << 5) | (sapi << 2) | (cr << 1) | EA;
976
977 /*
978 * control field 8 7 6 5 4 3 2 1
979 * I format ----N(R)--- P ----N(S)--- 0
980 * S format ----N(R)--- P/F S S 0 1
981 * U format U U U P/F U U 1 1
982 */
983 if ((type & 0x01) EQ 0)
984 pOutFrame[offset+1] = (nr << 5) | (p_bit << 4) | (ns << 1); /* I format */
985 else if ((type & 0x02) EQ 0)
986 pOutFrame[offset+1] = (nr << 5) | (p_bit << 4) | type; /* S format */
987 else
988 pOutFrame[offset+1] = (p_bit << 4) | type; /* U format */
989
990 /*
991 * length field 8 3 2 1
992 * -----length indicator----- M EL
993 */
994 pOutFrame[offset+2] = (length << 2) | (m_bit << 1) | EL;
995
996 /*
997 * LINT Warning 662: Possible creation of out-of-bounds pointer ... and
998 * LINT Warning 669: Possible data overrun for function 'memcpy ... and
999 * LINT Warning 671: Possibly passing to function 'memset ...
1000 * can be ignored because the sum of offset, 3 plus maxlength (length) does
1001 * never exceed the maximal size of pOutFrame[].
1002 */
1003 if (length && pInfoBuffer)
1004 {/* copy info bits */
1005 memcpy (&pOutFrame[offset+3], pInfoBuffer + (InfoOffset ? InfoOffset : 3), length);
1006 offset += length;
1007 maxlength -= length;
1008 }
1009
1010 /* fill remain of the frame with 0x2b */
1011 memset (&pOutFrame[offset+3], 0x2b, maxlength);
1012
1013 #undef SPARE
1014 #undef LPD
1015 #undef EA
1016 #undef EL
1017 }/* endfunc com_build_frame */
1018
1019 /*
1020 +--------------------------------------------------------------------+
1021 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
1022 | STATE : code ROUTINE : com_data_ind |
1023 +--------------------------------------------------------------------+
1024
1025 PURPOSE : Indicates a downlinked message to RR. The queue which is
1026 taken depend on the sapi value. In case of sapi=0 the function
1027 checks the layer 3 message for a channel release additionally.
1028 This is done to speed up the release procedure.
1029
1030 */
1031 GLOBAL void com_data_ind (UBYTE ch_type, UBYTE sapi, ULONG fn)
1032 {
1033 GET_INSTANCE_DATA;
1034 T_DL_DATA_IND *in_msg;
1035
1036 #if defined(INVOKE_SIGNAL)
1037 if (dl_data->interrupt_context)
1038 {
1039 sig_invoke_com_data_ind (ch_type, sapi, fn);
1040 return;
1041 }
1042 #endif /* INVOKE_SIGNAL */
1043
1044 if (sapi EQ PS_SAPI_0)
1045 {
1046 in_msg = dl_data->dcch0_in_msg;
1047
1048 if (in_msg)
1049 { /*
1050 * Purpose: Check if message is channel release, then start release
1051 * of connection. This will be done to speed up the DISC process.
1052 */
1053 /*lint -e415 (Warning -- access of out-of-bounds pointer) */
1054 /*lint -e416 (Warning -- creation of out-of-bounds pointer) */
1055 if ((in_msg->sdu.buf[3] EQ 0x06) AND /* PD RR */
1056 (in_msg->sdu.buf[4] EQ 0x0D)) /* MT channel release */
1057 {
1058 /*lint +e416 (Warning -- creation of out-of-bounds pointer) */
1059 /*lint +e415 (Warning -- access of out-of-bounds pointer) */
1060 /*
1061 * Send immediately (on the next uplink opportunity) a DISC frame
1062 * on DCCH.
1063 * Disable dedicated mode -> restrain measurement reports
1064 */
1065 dl_data->dcch0_disc_request = TRUE;
1066 DL_OFFLINE_TRACE(TRACE_DL_EVENT, C_DCCH0, ch_type, "CHANNEL REL received");
1067 #if !defined(LATE_LEAVING_DEDICATED)
1068 com_leave_dedicated (ch_type);
1069 #endif /* LATE_LEAVING_DEDICATED */
1070 }
1071 }
1072 }
1073 else
1074 {
1075 in_msg = dl_data->dcch3_in_msg;
1076 }
1077
1078 if (in_msg)
1079 {
1080 in_msg->ch_type = ch_type;
1081 in_msg->sapi = sapi;
1082 drr_dl_data_ind (sapi, fn);
1083 }
1084 else
1085 {
1086 DL_OFFLINE_TRACE (TRACE_DL_EVENT,
1087 (sapi EQ PS_SAPI_0) ? C_DCCH0 : C_DCCH3, ch_type, "dcchx_in_msg=NULL");
1088 }
1089 }
1090
1091 #if !defined(NTRACE)
1092 #if defined(DL_TRACE_ENABLED) && defined(DL_IMMEDIATE_TRACE)
1093 /*
1094 +--------------------------------------------------------------------+
1095 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
1096 | STATE : code ROUTINE : com_l2trace |
1097 +--------------------------------------------------------------------+
1098
1099 PURPOSE : Send L2 trace.
1100
1101 */
1102
1103 GLOBAL void com_l2trace (UBYTE trace_type,
1104 UBYTE channel, UBYTE ch_type, T_TIME trace_time, UBYTE* data)
1105 {
1106 GET_INSTANCE_DATA;
1107 ULONG trace_mask;
1108
1109 #ifdef TI_PS_HCOMM_CHANGE
1110 vsi_gettracemask(_hCommDL, _hCommDL, &trace_mask);
1111 #else
1112 vsi_gettracemask(hCommDL, hCommDL, &trace_mask);
1113 #endif
1114 if ((trace_mask & TC_USER1) EQ 0)
1115 return;
1116
1117 if (trace_time EQ 0)
1118 vsi_t_time (VSI_CALLER &trace_time);
1119
1120 #if defined(INVOKE_SIGNAL)
1121 if (dl_data->interrupt_context)
1122 {
1123 sig_invoke_com_l2trace (trace_type, channel, ch_type, trace_time, data);
1124 return;
1125 }
1126 #endif /* INVOKE_SIGNAL */
1127 dl_fast_trace(trace_type, channel, ch_type, trace_time, trace_mask, data);
1128 }
1129 #endif /* DL_TRACE_ENABLED && DL_IMMEDIATE_TRACE */
1130
1131 /*
1132 +--------------------------------------------------------------------+
1133 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
1134 | STATE : code ROUTINE : com_l3trace |
1135 +--------------------------------------------------------------------+
1136
1137 PURPOSE : Send L3 trace.
1138
1139 */
1140
1141 GLOBAL void com_l3trace (UBYTE type, UBYTE ch_type, UBYTE *frame)
1142 {
1143 GET_INSTANCE_DATA;
1144 ULONG trace_mask;
1145
1146 #ifdef TI_PS_HCOMM_CHANGE
1147 vsi_gettracemask(_hCommDL, _hCommDL, &trace_mask);
1148 #else
1149 vsi_gettracemask(hCommDL, hCommDL, &trace_mask);
1150 #endif
1151 if ((trace_mask & TC_USER4) EQ 0)
1152 return;
1153
1154 #if defined(INVOKE_SIGNAL)
1155 if (dl_data->interrupt_context)
1156 {
1157 sig_invoke_com_l3trace (type, ch_type, frame);
1158 return;
1159 }
1160 #endif /* INVOKE_SIGNAL */
1161
1162 if (type EQ TRACE_UPLINK)
1163 { /* uplink acknowledged */
1164 T_DL_DATA_REQ *d = (T_DL_DATA_REQ *)frame;
1165 com_print_l3trace (TRACE_UPLINK, ch_type, d->sapi, (UBYTE *)&d->sdu);
1166 }
1167 else if (type EQ TRACE_DOWNLINK)
1168 { /* downlink */
1169 T_DL_DATA_IND *d = (T_DL_DATA_IND *)frame;
1170 com_print_l3trace (TRACE_DOWNLINK, ch_type, d->sapi, (UBYTE *)&d->sdu);
1171 }
1172 else if ((type EQ TRACE_UACK_UP) OR (type EQ TRACE_UACK_DN))
1173 {
1174 com_print_l3trace (type, ch_type, PS_SAPI_0, frame);
1175 }
1176 }
1177
1178 GLOBAL void com_print_l3trace (UBYTE type, UBYTE ch_type, UBYTE sapi, UBYTE *l3msg)
1179 {
1180 char description[40];
1181
1182 switch (type)
1183 {
1184 case TRACE_UPLINK:
1185 case TRACE_DOWNLINK:
1186 {
1187 T_sdu *sdu = (T_sdu *)l3msg;
1188 sprintf (description, "L3 %s ch=%u SAPI%u",
1189 type EQ TRACE_UPLINK ? "UP" : "DN", ch_type, sapi);
1190 #ifdef TI_PS_HCOMM_CHANGE
1191 TRACE_BINDUMP(_hCommDL, TC_USER4, description,
1192 sdu->buf+(sdu->o_buf>>3), (sdu->l_buf>>3));
1193 #else
1194 TRACE_BINDUMP(hCommDL, TC_USER4, description,
1195 sdu->buf+(sdu->o_buf>>3), (sdu->l_buf>>3));
1196 #endif
1197 }
1198 break;
1199 case TRACE_UACK_UP:
1200 case TRACE_UACK_DN:
1201 if (GET_BTER_FORMAT (&l3msg[0]) EQ SHORT_L2_HEADER_TYPE_1)
1202 {
1203 sprintf (description, "L3 %s ch=%u SAPI%u RR Short PD header",
1204 type EQ TRACE_UACK_UP ? "UP" : "DN", ch_type, sapi);
1205 #ifdef TI_PS_HCOMM_CHANGE
1206 TRACE_BINDUMP(_hCommDL, TC_USER4, description, l3msg, DL_N201_SACCH_Bter);
1207 #else
1208 TRACE_BINDUMP(hCommDL, TC_USER4, description, l3msg, DL_N201_SACCH_Bter);
1209 #endif
1210 }
1211 else
1212 {
1213 sprintf (description, "L3 %s ch=%u SAPI%u",
1214 type EQ TRACE_UACK_UP ? "UP" : "DN", ch_type, sapi);
1215 #ifdef TI_PS_HCOMM_CHANGE
1216 TRACE_BINDUMP(_hCommDL, TC_USER4, description, l3msg, DL_N201_SACCH_A_B);
1217 #else
1218 TRACE_BINDUMP(hCommDL, TC_USER4, description, l3msg, DL_N201_SACCH_A_B);
1219 #endif
1220 }
1221 break;
1222 }
1223 }
1224 #endif /* !NTRACE */
1225
1226 /*
1227 +--------------------------------------------------------------------+
1228 | PROJECT : GSM-PS (6147) MODULE : DL_COM |
1229 | STATE : code ROUTINE : com_init_data |
1230 +--------------------------------------------------------------------+
1231
1232 PURPOSE : Initializes the data for one instance.
1233
1234 */
1235
1236 GLOBAL void com_init_data (void)
1237 {
1238 GET_INSTANCE_DATA;
1239 TRACE_FUNCTION ("com_init_data()");
1240
1241 memset (dl_data, 0, sizeof (T_DL_DATA_STORE));
1242
1243 dl_data->cch[C_DCCH0].T200_counter = 0;
1244 dl_data->cch[C_DCCH3].T200_counter = 0;
1245 dl_data->cch[C_SACCH0].T200_counter = 0;
1246 dl_data->dcch0_in_msg = NULL;
1247 dl_data->dcch3_in_msg = NULL;
1248
1249 dl_data->dcch0_disc_request = FALSE;
1250 dl_data->dcch3_disc_request = FALSE;
1251 dl_data->RR_dedicated = FALSE;
1252 dl_data->fn = NOT_PRESENT_32BIT;
1253
1254 #if defined(INVOKE_SIGNAL)
1255 sig_init_signal_data ();
1256 #endif /* INVOKE_SIGNAL */
1257 }
1258
1259
1260 #if defined (DL_TRACE_ENABLED) || defined (FF_EM_MODE)
1261 /*
1262 * Some of the functions originally designed for DL tracing are used as well for
1263 * the engineering mode and therefore defined here.
1264 */
1265
1266 GLOBAL void com_semaphore_err (void)
1267 {
1268 #if defined(_SIMULATION_)
1269 SYST_TRACE ("DL:error:semaphore");
1270 TRACE_ASSERT (1);
1271 #else /* _SIMULATION_ */
1272 static UCHAR out = 0;
1273 if (!out)
1274 {
1275 out = 1;
1276 SYST_TRACE ("DL:error:semaphore");
1277 vsi_t_sleep(VSI_CALLER 10000);
1278 TRACE_ASSERT (1);
1279 }
1280 #endif /* _SIMULATION_ */
1281 }
1282
1283 GLOBAL int com_enter_critical_section (T_HANDLE sem)
1284 {
1285 if (vsi_s_get (VSI_CALLER sem) NEQ VSI_OK)
1286 {
1287 com_semaphore_err();
1288 return -1;
1289 }
1290 else
1291 {
1292 return 0;
1293 }
1294 }/*endfunc com_enter_critical_section*/
1295
1296 GLOBAL int com_leave_critical_section (T_HANDLE sem)
1297 {
1298 if (vsi_s_release (VSI_CALLER sem) NEQ VSI_OK)
1299 {
1300 com_semaphore_err();
1301 return -1;
1302 }
1303 else
1304 {
1305 return 0;
1306 }
1307 }/* endfunc com_leave_critical_section */
1308
1309 #if !defined(DL_IMMEDIATE_TRACE)
1310 GLOBAL int com_semaphore_state (T_HANDLE sem)
1311 {
1312 USHORT semCount;
1313
1314 if (vsi_s_status (VSI_CALLER sem, &semCount) NEQ VSI_OK)
1315 {
1316 com_semaphore_err ();
1317 return -1;
1318 }
1319 if (semCount EQ 0)
1320 {
1321 SYST_TRACE ("DL:semCount == 0");
1322 return 1;
1323 }
1324 else
1325 return 0;
1326 }
1327 #endif /* !DL_IMMEDIATE_TRACE */
1328 #endif /* defined (DL_TRACE_ENABLED) || defined (FF_EM_MODE) */
1329
1330 #endif /* DL_COM_C */