comparison src/g23m-fad/l2r/l2r_dnf.c @ 1:d393cd9bb723

src/g23m-*: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:40:46 +0000
parents
children
comparison
equal deleted inserted replaced
0:b6a5e36de839 1:d393cd9bb723
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : CSD (8411)
4 | Modul : L2r_dnf.c
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 procedures and functions for
18 | the component L2R of the base station
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef L2R_DNF_C
23 #define L2R_DNF_C
24 #endif
25
26 #define ENTITY_L2R
27
28 /*==== INCLUDES ===================================================*/
29
30 #include <string.h>
31 #include "typedefs.h"
32 #include "pconst.cdg"
33 #include "vsi.h"
34 #include "macdef.h"
35 #include "custom.h"
36 #include "gsm.h"
37 #include "cus_l2r.h"
38 #include "cnf_l2r.h"
39 #include "mon_l2r.h"
40 #include "prim.h"
41 #include "pei.h"
42 #include "tok.h"
43 #include "dti.h" /* functionality of the dti library */
44
45 #include "cl_ribu.h"
46 #include "l2r.h"
47
48 /*==== CONST =======================================================*/
49
50 /*==== TYPES =======================================================*/
51
52 /*==== VAR EXPORT ==================================================*/
53
54 /*==== VAR LOCAL ===================================================*/
55
56 /*==== FUNCTIONS ===================================================*/
57
58 /*
59 +------------------------------------------------------------------------------
60 | Function : dn_init
61 +------------------------------------------------------------------------------
62 | Description : initialise the l2r data for the downlink process
63 |
64 | Parameters : -
65 |
66 |
67 | Return : -
68 +------------------------------------------------------------------------------
69 */
70
71 GLOBAL void dn_init(T_DN *ddn)
72 {
73 TRACE_FUNCTION ("dn_init()");
74
75 ddn->FlowCtrlUsed = FALSE;
76 ddn->DnFlow = FL_INACTIVE;
77 ddn->UpFlow = FL_INACTIVE;
78 #ifdef L2R_TRACE_FLOW
79 ddn->LastSentFlow = FL_INVALID;
80 #endif
81 ddn->FlowThresh = MAX_DPRIM_RIBU_SIZE / 2;
82 ddn->LastState = 0 << SO_SA_BIT | 0 << SO_SB_BIT;
83
84 ddn->RiBu.idx.depth = MAX_DPRIM_RIBU_SIZE;
85 INIT_STATE (DN_LL, IW_IDLE);
86 INIT_STATE (DN_UL, IW_IDLE);
87 INIT_STATE (DN, DN_DISCONNECTED);
88 }
89
90 /*
91 +------------------------------------------------------------------------------
92 | Function : dn_check_flow
93 +------------------------------------------------------------------------------
94 | Description : checks flow control staus
95 |
96 | Parameters : -
97 |
98 |
99 | Return : -
100 +------------------------------------------------------------------------------
101 */
102
103 GLOBAL void dn_check_flow(void)
104 {
105 T_DN *ddn = &l2r_data->dn;
106
107 TRACE_FUNCTION ("dn_check_flow()");
108
109 if (!ddn->FlowCtrlUsed)
110 {
111 return;
112 }
113
114 if (ddn->RiBu.idx.filled >= ddn->FlowThresh)
115 {
116 switch (ddn->DnFlow)
117 {
118 case FL_ACTIVE:
119 return;
120
121 case FL_INACTIVE:
122 ddn->DnFlow = FL_ACTIVE;
123 break;
124 }
125 }
126 else
127 {
128 switch (ddn->DnFlow)
129 {
130 case FL_ACTIVE:
131 ddn->DnFlow = FL_INACTIVE;
132 break;
133
134 case FL_INACTIVE:
135 return;
136 }
137 }
138 sig_dn_up_flow (ddn->DnFlow);
139 }
140
141 /*
142 +------------------------------------------------------------------------------
143 | Function : dn_next_frame
144 +------------------------------------------------------------------------------
145 | Description : Local function, which is used by up_copy_data_from_l2r
146 | to advance to the next frame in the primitive.
147 | The variable primDesc of the calling function is updated.
148 |
149 | Parameters : primDesc -
150 |
151 | Return : 1 -
152 | 0 -
153 +------------------------------------------------------------------------------
154 */
155
156 LOCAL UBYTE dn_next_frame(T_P_DPRIM_DESCRIPTOR *primDesc)
157 {
158 T_DN *ddn = &l2r_data->dn;
159
160 #ifdef _SIMULATION_
161 TRACE_FUNCTION ("dn_next_frame()");
162 #endif
163
164 (*primDesc)->index++; /* next frame */
165
166 if ((*primDesc)->index >= (*primDesc)->nFr)
167 {
168 #ifdef _SIMULATION_
169 TRACE_EVENT ("next primitive");
170 #endif
171 cl_ribu_read_index(&ddn->RiBu.idx); /* point to next primitive */
172
173 if (!ddn->RiBu.idx.filled) /* no primitive is ready */
174 {
175 #ifdef _SIMULATION_
176 TRACE_EVENT ("no primitive is ready");
177 #endif
178 return (0);
179 }
180
181 *primDesc = ddn->RiBu._primDesc[ddn->RiBu.idx.ri]; /* point to next primitive descriptor */
182 (*primDesc)->index = 0;
183 }
184 return (1);
185 }
186
187 /*
188 +------------------------------------------------------------------------------
189 | Function : dn_copy_data_from_l2r
190 +------------------------------------------------------------------------------
191 | Description : Copies data from l2r into ring buffer.
192 || Moreover the return value of the calling function
193 | bytesCopied are set
194
195 | Parameters : buf -
196 | len -
197 | sa -
198 | sb -
199 | flow -
200 | bytesCopied -
201 |
202 | Return : -
203 +------------------------------------------------------------------------------
204 */
205
206 LOCAL U16 dn_copy_data_from_l2r(U8 *buf, U16 len, U8 *sa, U8 *sb, U8 *flow)
207 {
208 T_DN *ddn = &l2r_data->dn;
209
210 T_P_DPRIM_DESCRIPTOR primDesc;
211 T_P_L2R_FRAME frame;
212
213 register T_P_UBYTE pFrame;
214 register T_P_UBYTE pBuf;
215 register T_P_UBYTE pStat;
216
217 USHORT bytesToCopy;
218 USHORT blocklen;
219 UBYTE frameCount;
220 UBYTE statOct;
221
222 #ifdef _SIMULATION_
223 TRACE_EVENT ("dn_copy_data_from_l2r()");
224 #endif
225
226 ddn->ReportMrgFlow = FALSE;
227
228 if (!ddn->RiBu.idx.filled) /* don't copy into buffer if no primitive is ready */
229 {
230 #ifdef _SIMULATION_
231 TRACE_EVENT ("no primitive ready");
232 #endif
233 switch (ddn->MrgFlow)
234 {
235 case FL_ACTIVE:
236 *flow = DTI_FLOW_OFF;
237 break;
238 case FL_INACTIVE:
239 *flow = DTI_FLOW_ON;
240 break;
241 }
242 *sa = GET_SO_SA_BIT(ddn->LastState);
243 *sb = GET_SO_SB_BIT(ddn->LastState);
244 return 0;
245 }
246
247 if (ddn->ULFlow EQ FL_ACTIVE)
248 {
249 len = 0; /* upper layer has raised flow control; don't send data */
250 }
251
252 bytesToCopy = len;
253 primDesc = ddn->RiBu._primDesc[ddn->RiBu.idx.ri]; /* point to current primitive descriptor */
254
255 if (primDesc->nFr EQ 0) /* skip empty primitive */
256 {
257 #ifdef _SIMULATION_
258 TRACE_EVENT ("empty primitive");
259 #endif
260 switch (ddn->MrgFlow)
261 {
262 case FL_ACTIVE:
263 *flow = DTI_FLOW_OFF;
264 break;
265 case FL_INACTIVE:
266 *flow = DTI_FLOW_ON;
267 break;
268 }
269 *sa = GET_SO_SA_BIT(ddn->LastState);
270 *sb = GET_SO_SB_BIT(ddn->LastState);
271 return 0;
272 }
273
274 #ifdef _TARGET_
275 if (primDesc->prim->data_size > DATA_SIZE_SHORT)
276 {
277 frameCount = 1;
278 }
279 else
280 {
281 frameCount = 2;
282 }
283 #else
284 {
285 frameCount = 100;
286 }
287 #endif
288
289 frame = (*primDesc->dadr)[primDesc->index]; /* dn_copy_data_from_l2r: point to current l2r frame in primitive */
290 pBuf = buf; /* point to destination buffer */
291 pFrame = &((*frame)[primDesc->offset]);
292 pStat = &((*frame)[primDesc->off_status]);
293
294 if (pFrame EQ pStat)
295 {
296 /* current byte is status octet */
297 ddn->LastState = *pFrame & SO_STATUS_BITS_MASK;
298 }
299
300 /* merge flow control conditions */
301
302 switch (ddn->MrgFlow)
303 {
304 case FL_ACTIVE:
305 *flow = DTI_FLOW_OFF;
306 break;
307 case FL_INACTIVE:
308 *flow = DTI_FLOW_ON;
309 break;
310 }
311
312 *sa = GET_SO_SA_BIT(ddn->LastState);
313 *sb = GET_SO_SB_BIT(ddn->LastState);
314
315 /************************************************************************************
316 * loop until either
317 * - no more data are available or
318 * - status in L2R frame changes or
319 * - buffer for data is full
320 ************************************************************************************/
321
322 for (;;)
323 {
324 blocklen = pStat - pFrame;
325
326 if (blocklen EQ 0)
327 {
328 /*
329 * current byte is status octet;
330 * only in the first pass of the loop, there may be no status octet
331 */
332
333 /*****************************
334 * evaluate status bits
335 *****************************/
336 statOct = *pFrame;
337 if (ddn->LastState NEQ (statOct & SO_STATUS_BITS_MASK))
338 {
339 /*
340 * Status has changed.
341 * We have to stop,
342 * since only one state can be transmitted to the upper layer.
343 */
344 primDesc->offset = primDesc->off_status = pFrame - (T_P_UBYTE)frame;
345
346 #ifdef _SIMULATION_
347 TRACE_EVENT ("return because of status change");
348 #endif
349 return len - bytesToCopy;
350 }
351
352 pFrame++;
353
354 /************************************
355 * evaluate address bits
356 ************************************/
357
358 statOct &= SO_ADR_MASK;
359
360 switch (statOct)
361 {
362 case SO_BREAK_ACK:
363 case SO_BREAK_REQ:
364 case SO_END_EMPTY:
365 /*
366 * no more data in this frame
367 */
368 if (dn_next_frame(&primDesc) EQ 0) /* no more data available */
369 {
370 primDesc->offset = 0;
371 primDesc->off_status = 0;
372
373 #ifdef _SIMULATION_
374 TRACE_EVENT ("return because no more data available");
375 #endif
376 return len - bytesToCopy; /* this much data could be copied */
377 }
378
379 frameCount--;
380
381 if (frameCount EQ 0)
382 {
383 primDesc->offset = 0;
384 primDesc->off_status = 0;
385 #ifdef _SIMULATION_
386 TRACE_EVENT ("return because number of frames reached");
387 #endif
388 return len - bytesToCopy; /* this much data could be copied */
389 }
390
391 frame = (*primDesc->dadr)[primDesc->index]; /* dn_copy_data_from_l2r */
392 pFrame = (T_P_UBYTE)frame;
393 pStat = (T_P_UBYTE)frame;
394 continue; /* continue with next frame */
395
396 case SO_END_FULL:
397 pStat = &((*frame)[primDesc->prim->data_size]);
398 blocklen = pStat - pFrame;
399 break;
400
401 case SO_TWO_OCTET:
402 blocklen = *pFrame++ & SO_ADR_MASK_TWO_OCT;
403 pStat = pFrame + blocklen;
404 break;
405
406 default:
407 blocklen = statOct;
408 pStat = pFrame + blocklen;
409 break;
410 }
411 }
412
413 if (bytesToCopy < blocklen)
414 {
415 /***************************************
416 * There is not enough space in the
417 * buffer to copy the complete block
418 ***************************************/
419
420 T_P_UBYTE pEnd = pFrame + bytesToCopy; /* save end mark */
421
422 while (pFrame < pEnd)
423 {
424 *pBuf++ = *pFrame++;
425 }
426
427 if (pFrame >= &((*frame)[primDesc->prim->data_size]))
428 {
429 /*
430 * end of frame reached
431 * actually this case can never occur,
432 * since bytesToCopy < blocklen
433 */
434 dn_next_frame(&primDesc);
435 primDesc->offset = 0;
436 primDesc->off_status = 0;
437 }
438 else
439 {
440 primDesc->offset = pFrame - (T_P_UBYTE)frame;
441 primDesc->off_status = pStat - (T_P_UBYTE)frame;
442 }
443
444 #ifdef _SIMULATION_
445 TRACE_EVENT ("return because buffer is full");
446 #endif
447 return len; /* this much data could be copied */
448
449 }
450 else /* bytesToCopy >= blocklen */
451 {
452 /***************************************
453 * Copy the complete block
454 ***************************************/
455
456 bytesToCopy -= blocklen;
457
458 while (pFrame < pStat)
459 {
460 *pBuf++ = *pFrame++;
461 }
462
463 if (pFrame >= &((*frame)[primDesc->prim->data_size])) /* end of frame reached */
464 {
465 if (dn_next_frame(&primDesc) EQ 0) /* no more data available */
466 {
467 #ifdef _SIMULATION_
468 TRACE_EVENT ("return because no more data available");
469 #endif
470 return len - bytesToCopy; /* this much data could be copied */
471 }
472
473 frameCount--;
474
475 if (frameCount EQ 0)
476 {
477 primDesc->offset = 0;
478 primDesc->off_status = 0;
479
480 #ifdef _SIMULATION_
481 TRACE_EVENT ("return because number of frames reached");
482 #endif
483 return len - bytesToCopy; /* this much data could be copied */
484 }
485
486 frame = (*primDesc->dadr)[primDesc->index]; /* dn_copy_data_from_l2r */
487 pFrame = (T_P_UBYTE)frame;
488 pStat = (T_P_UBYTE)frame;
489 }
490
491 if (bytesToCopy EQ 0)
492 {
493 primDesc->offset = pFrame - (T_P_UBYTE)frame;
494 primDesc->off_status = pStat - (T_P_UBYTE)frame;
495
496 #ifdef _SIMULATION_
497 TRACE_EVENT ("return because all data are copied");
498 #endif
499 return len; /* this much data could be copied */
500 }
501
502 } /* bytesToCopy >= blocklen */
503 } /* for (;;) */
504 }
505
506 /*
507 +------------------------------------------------------------------------------
508 | Function : dn_send_data_ind
509 +------------------------------------------------------------------------------
510 | Description : This procedure copies data from the downlink ring buffer
511 | into a DTI_DATA_IND primitive
512 | and sends this primitive to the relay entity.
513 |
514 | Parameters : -
515 |
516 |
517 | Return : -
518 +------------------------------------------------------------------------------
519 */
520
521 GLOBAL void dn_send_data_ind(void)
522 {
523 T_DN *ddn = &l2r_data->dn;
524
525 TRACE_FUNCTION ("dn_send_data_ind()");
526
527 if (ddn->DtiConnected EQ FALSE)
528 {
529 TRACE_EVENT("DTI not connected, but dn_send_data_ind() called");
530 return;
531 }
532
533 {
534 USHORT len = L2R_FRAMES_PER_PRIM_MAX * (RLP_FRAME_SIZE_SHORT - HT_LEN - 1);
535 UBYTE sa;
536 UBYTE sb;
537 UBYTE flow;
538 T_desc2* desc;
539
540 PALLOC (dti_data_ind, DTI2_DATA_IND);
541
542 MALLOC (desc, (USHORT)(sizeof(T_desc2) - 1 + len));
543 desc->len = dn_copy_data_from_l2r ((U8*)&desc->buffer[0], len, &sa, &sb, &flow);
544 desc->size = desc->len;
545 desc->offset = 0;
546 desc->next = 0;
547
548 dti_data_ind->desc_list2.first = (ULONG)desc;
549 dti_data_ind->desc_list2.list_len = desc->len;
550
551 dti_data_ind->parameters.st_lines.st_line_sa = sa;
552 dti_data_ind->parameters.st_lines.st_line_sb = sb;
553 dti_data_ind->parameters.st_lines.st_flow = flow;
554 dti_data_ind->parameters.st_lines.st_break_len = DTI_BREAK_OFF;
555 dti_data_ind->parameters.p_id = DTI_PID_UOS;
556 dti_data_ind->link_id = ddn->link_id;
557
558 #ifdef L2R_TRACE_FLOW
559 if (ddn->LastSentFlow NEQ dti_data_ind->parameters.st_lines.st_flow)
560 {
561 switch (dti_data_ind->parameters.st_lines.st_flow)
562 {
563 case FL_ACTIVE:
564 TRACE_EVENT("DTI downlink: FL_ACTIVE");
565 break;
566
567 case FL_INACTIVE:
568 TRACE_EVENT("DTI downlink: FL_INACTIVE");
569 break;
570 }
571 ddn->LastSentFlow = dti_data_ind->parameters.st_lines.st_flow;
572 }
573 #endif
574
575 dti_send_data (
576 l2r_hDTI,
577 L2R_DTI_UP_DEF_INSTANCE,
578 L2R_DTI_UP_INTERFACE,
579 L2R_DTI_UP_CHANNEL,
580 dti_data_ind
581 );
582 }
583 }
584
585 /*
586 +------------------------------------------------------------------------------
587 | Function : dn_scan_break_req
588 +------------------------------------------------------------------------------
589 | Description : This procedure scans a rlp_data_ind primitive for L2R BREAK
590 | status octets. It returnes the index of the frame following
591 | the last BREAK status octet in the primitive.
592 | Moreover the total number of frames in the primitive
593 | as well as the status bits of the last BREAK are returned.
594 | In addition the x bit of the last status octet is returned.
595 | It is important to search the last BREAK in the primitive,
596 | because the data following a break signal
597 | are used in the case of no data compression.
598 |
599 | Parameters : data_ind -
600 | found
601 | index
602 | frames
603 | emptyfr
604 | sa
605 | sb
606 | flow_brk
607 | flow_gen
608 |
609 | Return : -
610 +------------------------------------------------------------------------------
611 */
612
613 GLOBAL void dn_scan_break_req
614 (
615 T_P_RLP_DATA_IND data_ind,
616 BOOL *found,
617 T_PRIM_INDEX *index,
618 T_PRIM_INDEX *frames,
619 T_PRIM_INDEX *emptyfr,
620 T_BIT *sa,
621 T_BIT *sb,
622 T_FLOW *flow_brk,
623 T_FLOW *flow_gen
624 )
625
626 {
627 T_PRIM_INDEX ind;
628 UBYTE off;
629 UBYTE statOct;
630 UBYTE brkStatOct = (UBYTE)(0 << SO_SA_BIT | 0 << SO_SB_BIT | 0 << SO_X_BIT);
631 UBYTE genStatOct = (UBYTE)(0 << SO_SA_BIT | 0 << SO_SB_BIT | 0 << SO_X_BIT);
632
633 T_P_L2R_FRAME frame;
634
635 TRACE_FUNCTION ("dn_scan_break_req()");
636
637 *found = FALSE;
638 *frames = data_ind->sdu.l_buf / (8 * data_ind->data_size + HT_LEN);
639 *emptyfr = 0;
640
641 frame = (T_P_L2R_FRAME)(data_ind->sdu.buf + (data_ind->sdu.o_buf>>3) + HEADER_LEN);
642 off = 0;
643 ind = 0;
644
645 while (ind < *frames)
646 {
647 statOct = (*frame)[off];
648
649 switch (statOct & SO_ADR_MASK)
650 {
651 case SO_BREAK_REQ:
652 *found = TRUE;
653 *index = ind + 1;
654 brkStatOct = statOct;
655 genStatOct = statOct;
656 ind++;
657 frame = (T_P_L2R_FRAME)((UBYTE*)frame + data_ind->data_size + HT_LEN);
658 off = 0;
659 break;
660
661 case SO_END_EMPTY:
662 if (off EQ 0)
663 {
664 (*emptyfr)++;
665 }
666 /* fall through!!! */
667
668 case SO_BREAK_ACK:
669 case SO_END_FULL:
670 genStatOct = statOct;
671 ind++;
672 frame = (T_P_L2R_FRAME)((UBYTE*)frame + data_ind->data_size + HT_LEN);
673 off = 0;
674 break;
675
676 case SO_TWO_OCTET:
677 genStatOct = statOct;
678 off += ((*frame)[off] & SO_ADR_MASK_TWO_OCT) + 2;
679 if (off >= data_ind->data_size)
680 {
681 ind++;
682 frame = (T_P_L2R_FRAME)((UBYTE*)frame + data_ind->data_size + HT_LEN);
683 off = 0;
684 }
685 break;
686
687 default:
688 genStatOct = statOct;
689 off += (statOct & SO_ADR_MASK) + 1;
690 if (off >= data_ind->data_size)
691 {
692 ind++;
693 frame = (T_P_L2R_FRAME)((UBYTE*)frame + data_ind->data_size + HT_LEN);
694 off = 0;
695 }
696 break;
697 }
698 }
699
700 if (*found)
701 {
702 *sa = GET_SO_SA_BIT(brkStatOct);
703 *sb = GET_SO_SB_BIT(brkStatOct);
704 }
705 else
706 {
707 *sa = GET_SO_SA_BIT(genStatOct);
708 *sb = GET_SO_SB_BIT(genStatOct);
709 }
710
711 if (l2r_data->dn.FlowCtrlUsed)
712 {
713 if (GET_SO_X_BIT (brkStatOct) EQ 0)
714 {
715 *flow_brk = FL_INACTIVE;
716 }
717 else
718 {
719 *flow_brk = FL_ACTIVE;
720 }
721
722 if (GET_SO_X_BIT (genStatOct) EQ 0)
723 {
724 *flow_gen = FL_INACTIVE;
725 }
726 else
727 {
728 *flow_gen = FL_ACTIVE;
729 }
730 }
731 else
732 {
733 *flow_brk = FL_INACTIVE;
734 *flow_gen = FL_INACTIVE;
735 }
736 }
737
738 /*
739 +------------------------------------------------------------------------------
740 | Function : dn_free_prim
741 +------------------------------------------------------------------------------
742 | Description :
743 |
744 | Parameters : primDesc -
745 |
746 |
747 | Return :
748 +------------------------------------------------------------------------------
749 */
750
751 LOCAL void dn_free_prim(T_P_DPRIM_DESCRIPTOR primDesc)
752 {
753 TRACE_FUNCTION ("dn_free_prim()");
754
755 if (primDesc->prim NEQ NULL)
756 {
757 PFREE (primDesc->prim);
758 primDesc->prim = NULL;
759 primDesc->nFr = 0;
760 primDesc->index = 0;
761 primDesc->offset = 0;
762 primDesc->off_status = 0;
763 }
764 }
765
766 /*
767 +------------------------------------------------------------------------------
768 | Function : dn_free_all_prims
769 +------------------------------------------------------------------------------
770 | Description : frees all primititives
771 |
772 | Parameters : -
773 |
774 |
775 | Return : -
776 +------------------------------------------------------------------------------
777 */
778
779 GLOBAL void dn_free_all_prims(void)
780 {
781 T_DN *ddn = &l2r_data->dn;
782
783 T_PRIM_DESC_RIBU_INDEX n;
784
785 TRACE_FUNCTION ("dn_free_all_prims()");
786
787 for (n = 0; n < ddn->RiBu.idx.depth; n++)
788 {
789 dn_free_prim (ddn->RiBu._primDesc[n]);
790 }
791 }
792
793 /*
794 +------------------------------------------------------------------------------
795 | Function : dn_cond_free_prims
796 +------------------------------------------------------------------------------
797 | Description : frees all primitive if r
798 |
799 | Parameters : -
800 |
801 |
802 | Return : -
803 +------------------------------------------------------------------------------
804 */
805
806 GLOBAL void dn_cond_free_prims(void)
807 {
808 T_DN *ddn = &l2r_data->dn;
809
810 TRACE_FUNCTION ("dn_cond_free_prims()");
811
812 while (ddn->RiBu.free NEQ ddn->RiBu.idx.ri)
813 {
814 dn_free_prim (ddn->RiBu._primDesc[ddn->RiBu.free]);
815
816 ddn->RiBu.free++;
817 if (ddn->RiBu.free EQ ddn->RiBu.idx.depth)
818 {
819 ddn->RiBu.free = 0;
820 }
821 }
822 }
823
824 /*
825 +------------------------------------------------------------------------------
826 | Function : dn_store_prim
827 +------------------------------------------------------------------------------
828 | Description :
829 |
830 | Parameters : data_ind -
831 | index -
832 |
833 | Return : -
834 +------------------------------------------------------------------------------
835 */
836
837 GLOBAL void dn_store_prim(T_P_RLP_DATA_IND data_ind, T_PRIM_INDEX index)
838 {
839 T_DN *ddn = &l2r_data->dn;
840
841 T_PRIM_INDEX m;
842 T_P_DPRIM_DESCRIPTOR primDesc;
843
844 T_PRIM_INDEX frames = data_ind->sdu.l_buf / (8 * data_ind->data_size + HT_LEN);
845 UBYTE *pos = data_ind->sdu.buf + (data_ind->sdu.o_buf>>3) + HEADER_LEN;
846
847 TRACE_FUNCTION ("dn_store_prim()");
848
849 primDesc = ddn->RiBu._primDesc[cl_ribu_write_index(&ddn->RiBu.idx)];
850
851 primDesc->prim = data_ind;
852 primDesc->index = index; /* if BREAK then not equal 0 */
853 primDesc->offset = 0;
854 primDesc->off_status = 0;
855 primDesc->nFr = frames;
856
857 for (m = 0; m < frames; m++)
858 {
859 (*primDesc->dadr)[m] = (T_P_L2R_FRAME)(pos + m * (data_ind->data_size + HT_LEN));
860 }
861
862 dn_check_flow();
863
864 if (GET_STATE (DN_UL) EQ IW_WAIT AND ddn->ULFlow EQ FL_INACTIVE AND
865 ddn->DtiConnected) /*jk: data send only when DTI connected*/
866 {
867 dn_send_data_ind();
868 SET_STATE (DN_UL, IW_IDLE);
869 }
870 }
871
872 /*
873 +--------------------------------------------------------------------+
874 | PROJECT : GSM-F&D (8411) MODULE : L2R_DNF |
875 | STATE : code ROUTINE : dn_init_ribu |
876 +--------------------------------------------------------------------+
877
878 PURPOSE :
879
880 */
881
882 GLOBAL void dn_init_ribu(void)
883 {
884 T_DN *ddn = &l2r_data->dn;
885
886 T_PRIM_DESC_RIBU_INDEX n;
887 T_PRIM_INDEX m;
888
889 TRACE_FUNCTION ("dn_init_ribu()");
890
891 cl_ribu_init(&ddn->RiBu.idx, ddn->RiBu.idx.depth);
892 ddn->RiBu.free = 0;
893
894 for (n = 0; n < ddn->RiBu.idx.depth; n++)
895 {
896 ddn->RiBu._primDesc[n] = &(ddn->PrimDesc[n]);
897 ddn->PrimDesc[n].nFr = 0;
898 ddn->PrimDesc[n].dadr = (T_P_ADR_VECTOR)&(ddn->AdrVec[n]); /* dn_init_ribu */
899 ddn->PrimDesc[n].index = 0;
900 ddn->PrimDesc[n].offset = 0;
901 ddn->PrimDesc[n].off_status = 0;
902 ddn->PrimDesc[n].prim = NULL;
903
904 for (m = 0; m < L2R_FRAMES_PER_PRIM_MAX; m++)
905 {
906 ddn->AdrVec[n][m] = NULL;
907 }
908 }
909 }
910
911 /*
912 +------------------------------------------------------------------------------
913 | Function : dn_cond_req_data
914 +------------------------------------------------------------------------------
915 | Description :
916 |
917 | Parameters : -
918 |
919 |
920 | Return : -
921 +------------------------------------------------------------------------------
922 */
923
924 GLOBAL void dn_cond_req_data(void)
925 {
926 T_DN *ddn = &l2r_data->dn;
927
928 TRACE_FUNCTION ("dn_cond_req_data()");
929
930 /* ring buffer full? */
931
932 if ((ddn->RiBu.idx.wi + 1) % ddn->RiBu.idx.depth EQ ddn->RiBu.free)
933 {
934 SET_STATE (DN_LL, IW_IDLE);
935 }
936 else
937 {
938 PALLOC (rlp_getdata_req, RLP_GETDATA_REQ);
939 PSENDX (RLP, rlp_getdata_req);
940 SET_STATE (DN_LL, IW_WAIT);
941 }
942 }
943
944 /*
945 +------------------------------------------------------------------------------
946 | Function : dn_store_status
947 +------------------------------------------------------------------------------
948 | Description :
949 |
950 | Parameters : flow -
951 |
952 |
953 | Return : -
954 +------------------------------------------------------------------------------
955 */
956
957 GLOBAL void dn_store_status(T_FLOW flow)
958 {
959 T_DN *ddn = &l2r_data->dn;
960
961 TRACE_FUNCTION ("dn_store_status()");
962
963 if (flow EQ ddn->LLFlow)
964 {
965 return;
966 }
967
968 ddn->LLFlow = flow;
969 dn_merge_flow();
970 sig_dn_up_ll_flow(ddn->LLFlow);
971 }
972
973 /*
974 +------------------------------------------------------------------------------
975 | Function : dn_merge_flow
976 +------------------------------------------------------------------------------
977 | Description :
978 |
979 | Parameters : -
980 |
981 |
982 | Return : -
983 +------------------------------------------------------------------------------
984 */
985
986 GLOBAL void dn_merge_flow(void)
987 {
988 T_DN *ddn = &l2r_data->dn;
989
990 TRACE_FUNCTION ("dn_merge_flow()");
991
992 if (ddn->FlowCtrlUsed AND (ddn->UpFlow EQ FL_ACTIVE OR ddn->LLFlow EQ FL_ACTIVE) )
993 {
994 if (ddn->MrgFlow EQ FL_INACTIVE)
995 {
996 ddn->ReportMrgFlow = TRUE;
997 /*
998 TRACE_EVENT("DN: Merged flow set active");
999 */
1000 }
1001 ddn->MrgFlow = FL_ACTIVE;
1002 }
1003 else
1004 {
1005 if (ddn->MrgFlow EQ FL_ACTIVE)
1006 {
1007 ddn->ReportMrgFlow = TRUE;
1008 /*
1009 TRACE_EVENT("DN: Merged flow set inactive");
1010 */
1011 }
1012 ddn->MrgFlow = FL_INACTIVE;
1013 }
1014 }
1015
1016 /*
1017 +------------------------------------------------------------------------------
1018 | Function : dn_cond_report_status
1019 +------------------------------------------------------------------------------
1020 | Description :
1021 |
1022 | Parameters : -
1023 |
1024 |
1025 | Return : -
1026 +------------------------------------------------------------------------------
1027 */
1028
1029 GLOBAL void dn_cond_report_status(void)
1030 {
1031 TRACE_FUNCTION ("dn_cond_report_status()");
1032
1033 if (l2r_data->dn.ReportMrgFlow AND GET_STATE (DN_UL) EQ IW_WAIT)
1034 {
1035 if (l2r_data->dn.DtiConnected) /*jk: data send only when DTI connected*/
1036 {
1037 dn_send_data_ind();
1038 SET_STATE (DN_UL, IW_IDLE);
1039 }
1040 }
1041 }
1042