comparison src/g23m-gsm/dl/dl_com.c @ 1:fa8dc04885d8

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