comparison src/g23m-gprs/grlc/grlc_tmf.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 : GPRS (8441)
4 | Modul : GRLC
5 +-----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +-----------------------------------------------------------------------------
17 | Purpose : This module implements local functions for service TC of
18 | entity GRLC.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef GRLC_TMF_C
23 #define GRLC_TMF_C
24 #endif
25
26 #define ENTITY_GRLC
27
28 /*==== INCLUDES =============================================================*/
29
30 #include <stdio.h>
31 #include <string.h>
32
33 #include "typedefs.h" /* to get Condat data types */
34 #include "vsi.h" /* to get a lot of macros */
35 #include "macdef.h"
36 #include "gprs.h"
37 #include "gsm.h" /* to get a lot of macros */
38 #include "ccdapi.h" /* to get CCD API */
39 #include "cnf_grlc.h" /* to get cnf-definitions */
40 #include "mon_grlc.h" /* to get mon-definitions */
41 #include "prim.h" /* to get the definitions of used SAP and directions */
42 #include "message.h" /* to get air message definitions */
43 #include "grlc.h" /* to get the global entity definitions */
44
45 #include "grlc_f.h" /* to get Process GRLC global function definitions */
46 #include "grlc_tmf.h" /* to get Service TM global function definitions */
47 #include "grlc_tms.h" /* to get Service TM inter signal definitions */
48 #include "grlc_rus.h" /* to get interface to service RU */
49 #include "grlc_rds.h" /* to get interface to service RD */
50 #include "grlc_gffs.h"
51 #include "grlc_meass.h"
52 #include "grlc_tpcs.h"
53 #include "cl_rlcmac.h"
54
55 /*==== CONST ================================================================*/
56 /*
57 * used in tm_compare_prim
58 */
59 #define SAME_RLC_MODE 0
60 #define DIFFERENT_RLC_MODE 1
61
62 #define PRIO_LOWER 0
63 #define PRIO_SAME 1
64 #define PRIO_HIGHER 2
65
66 #define THROUGHPUT_LOWER 0
67 #define THROUGHPUT_SAME 1
68 #define THROUGHPUT_HIGHER 2
69
70 #ifdef REL99
71 #define SAME_PFI 0
72 #define DIFF_PFI 1
73 #endif
74
75
76
77
78 /*==== DIAGNOSTICS ==========================================================*/
79
80 /*==== LOCAL VARS ===========================================================*/
81
82
83 /*==== PRIVATE FUNCTIONS ====================================================*/
84
85
86 LOCAL void tm_close_gaps_in_ctrl_blk_seq( UBYTE index );
87 /*==== PUBLIC FUNCTIONS =====================================================*/
88
89
90
91 /*
92 +------------------------------------------------------------------------------
93 | Function : tm_access_allowed
94 +------------------------------------------------------------------------------
95 | Description : The function tm_access_allowed() this function checks wheather
96 | access is allowed or not. The return is TRUE if access
97 | is allowed.
98 |
99 | Parameters : radio_prrio - radio priority for current primitive
100 |
101 +------------------------------------------------------------------------------
102 */
103 GLOBAL BOOL tm_access_allowed ( UBYTE radio_prio )
104 {
105 BOOL result = FALSE;
106 TRACE_FUNCTION( "tm_access_allowed" );
107
108 switch(grlc_data->uplink_tbf.ac_class)
109 {
110 case CGRLC_PCCCH_AC_ALLOWED:
111 result = TRUE;
112 break;
113 case CGRLC_PCCCH_AC_NOT_ALLOWED:
114 TRACE_EVENT(" grlc ACCESS NOT ALLOWED PBCCH:");
115 break;
116 case CGRLC_CCCH_AC_NOT_ALLOWED:
117 TRACE_EVENT("grlc ACCESS NOT ALLOWED CCCH");
118 break;
119 default:
120 if ( (radio_prio+3) <= grlc_data->uplink_tbf.ac_class)
121 result = TRUE;
122 else
123 TRACE_EVENT_P2("Radio prio to low : pdu_rp=%d net_rp=%d",radio_prio,grlc_data->uplink_tbf.ac_class);
124 break;
125 }
126
127
128 return(result);
129 } /* tm_access_allowed() */
130
131 /*
132 +------------------------------------------------------------------------------
133 | Function : tm_build_chan_req_des
134 +------------------------------------------------------------------------------
135 | Description : The function builds a channel request description. It is called
136 | during re-allocation or during uplink allocation on
137 | a dowlink TBF.
138 |
139 | Parameters : out_i - Function have to write the channel request description
140 | at this address
141 | p_ptr_i - Pointer to primitive which causes the channel request
142 | description
143 |
144 +------------------------------------------------------------------------------
145 */
146 GLOBAL void tm_build_chan_req_des ( T_chan_req_des * out_i,T_PRIM_QUEUE * p_ptr_i )
147 {
148
149 UBYTE next;
150
151 TRACE_FUNCTION( "tm_build_chan_req_des" );
152
153 grlc_data->uplink_tbf.ti = 0; /* no contention resolution needed */
154 out_i->peak_thr_class = p_ptr_i->prim_ptr->grlc_qos.peak;
155 out_i->radio_prio = p_ptr_i->prim_ptr->radio_prio;
156
157 /*
158 * set RLC-Mode and LLC-Mode
159 */
160 out_i->llc_pdu_type = LLC_NOT_ACK; /* that means not acknowledged */
161 if(p_ptr_i->prim_type EQ CGRLC_LLC_PRIM_TYPE_DATA_REQ)
162 { /* CGRLC_LLC_PRIM_TYPE_DATA_REQ */
163 out_i->rlc_mode = RLC_ACK_MODE; /* that means RLC mode acknowledged */
164 }
165 else
166 { /* CGRLC_LLC_PRIM_TYPE_UNITDATA_REQ */
167 out_i->rlc_mode = RLC_UNACK_MODE; /* that means RLC mode not acknowledged */
168 }
169
170 next = p_ptr_i->next;
171 out_i->rlc_octet_cnt = p_ptr_i->prim_ptr->sdu.l_buf/8 +1;
172 while (next < PRIM_QUEUE_SIZE_TOTAL)
173 {
174 out_i->rlc_octet_cnt +=
175 grlc_data->prim_queue[next].prim_ptr->sdu.l_buf/8 +1;
176 next = grlc_data->prim_queue[next].next;
177 }
178
179 if (grlc_data->testmode.mode EQ CGRLC_LOOP)
180 {
181 out_i->rlc_octet_cnt = 0;
182 TRACE_EVENT("open-ended tbf for testmode B requested");
183 }
184 return;
185
186 } /* tm_build_chan_req_des */
187
188
189
190 /*
191 +------------------------------------------------------------------------------
192 | Function : tm_send_tbf_rel
193 +------------------------------------------------------------------------------
194 | Description : The function tm_send_tbf_rel() builds CGRLC_TBF_REL_IND
195 | and send it.
196 |
197 | Parameters : TBP-Type - that have to be deleted
198 |
199 +------------------------------------------------------------------------------
200 */
201 GLOBAL void tm_send_tbf_rel ( T_TBF_TYPE tbf_i )
202 {
203 PALLOC(cgrlc_tbf_rel_ind,CGRLC_TBF_REL_IND);
204
205 TRACE_FUNCTION( "tm_send_tbf_rel" );
206
207
208 if(grlc_data->uplink_tbf.ti)
209 cgrlc_tbf_rel_ind->tbf_rel_cause = CGRLC_TBF_REL_CR_FAILED;
210 else if (grlc_data->N3102 EQ 0) /* tbf error with cell reselction*/
211 cgrlc_tbf_rel_ind->tbf_rel_cause = CGRLC_TBF_REL_WITH_CELL_RESELECT;
212 else
213 cgrlc_tbf_rel_ind->tbf_rel_cause = CGRLC_TBF_REL_NORMAL; /* Find condition for abnormal release */
214
215 grlc_data->uplink_tbf.ti = 0;
216
217 /*
218 * indicate if testmode or tbf_type is released
219 */
220
221 if((tbf_i NEQ TBF_TYPE_DL) AND /* Testmode released only in case of uplink tbf release*/
222 (grlc_test_mode_active()))
223 {
224 if (grlc_data->testmode.mode EQ CGRLC_TEST_RANDOM)
225 {
226 MFREE(grlc_data->testmode.ptr_test_data);
227 grlc_data->testmode.ptr_test_data = NULL;
228 }
229 grlc_data->testmode.mode = CGRLC_TEST_MODE_RELEASE;
230 cgrlc_tbf_rel_ind->tbf_rel_cause = CGRLC_TBF_REL_NORMAL;
231 }
232
233 #if defined REL99 AND defined TI_PS_FF_TI_PS_FF_TBF_EST_PACCH
234 if (tbf_i EQ TBF_TYPE_TP_ACCESS AND
235 grlc_data->tm.pacch_prr_pca_sent) /*PRR/PCA sent as POLL (tbf on pacch)*/
236 {
237 vsi_t_stop(GRLC_handle,T3168);
238 cgrlc_tbf_rel_ind->tbf_mode = CGRLC_TBF_MODE_UL;
239 grlc_data->tm.pacch_prr_pca_sent = FALSE;
240 sig_tm_gff_ul_deactivate();
241 }
242 else
243 #endif
244 if (tbf_i EQ TBF_TYPE_UL)
245 {
246 cgrlc_tbf_rel_ind->tbf_mode = CGRLC_TBF_MODE_UL;
247 grlc_data->rel_type |= REL_TYPE_UL;
248 sig_tm_gff_ul_deactivate();
249 }
250 else if (tbf_i EQ TBF_TYPE_DL)
251 {
252 cgrlc_tbf_rel_ind->tbf_mode = CGRLC_TBF_MODE_DL;
253 grlc_data->rel_type |= REL_TYPE_DL;
254 sig_tm_gff_dl_deactivate();
255 cgrlc_tbf_rel_ind->dl_trans_id = grlc_data->downlink_tbf.trans_id;
256 }
257 else
258 {
259 cgrlc_tbf_rel_ind->tbf_mode = CGRLC_TBF_MODE_DL_UL;
260 grlc_data->rel_type = REL_TYPE_DL_UL;
261 cgrlc_tbf_rel_ind->dl_trans_id = grlc_data->downlink_tbf.trans_id;
262 sig_tm_gff_ul_deactivate();
263 sig_tm_gff_dl_deactivate();
264 }
265
266
267 /*
268 * \ tbf_i | UL DL CONC
269 * \ |
270 * \ |
271 * \ |
272 * tbf_type \ |
273 * -----------+-----------
274 * NULL | x x x
275 * UL | x - x
276 * DL | - x x
277 * CONC | - - x
278 *
279 * x means, that no more TBF is existing
280 * - means, that a TBF is still existing
281 */
282
283 if( tbf_i EQ TBF_TYPE_CONC OR
284 grlc_data->tbf_type EQ TBF_TYPE_NULL OR
285 grlc_data->tbf_type EQ tbf_i )
286 {
287 cgrlc_tbf_rel_ind->v_c_value = TRUE;
288
289 meas_grlc_c_get_c_value( &cgrlc_tbf_rel_ind->c_value );
290 meas_c_restart( );
291
292 }
293 else
294 {
295 cgrlc_tbf_rel_ind->v_c_value = FALSE;
296 }
297
298 #if defined (_TARGET_)
299 switch(cgrlc_tbf_rel_ind->tbf_mode)
300 {
301 case CGRLC_TBF_MODE_UL:
302 #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH
303 case CGRLC_TBF_MODE_2PA:
304 #endif
305
306 TRACE_EVENT_P4("UL_TBF_REL:nr_of_crc_errors= %ld ul_call_errors=%ld dl_call_errors=%ld rel_type=%d",
307 grlc_data->nr_of_crc_errors,
308 grlc_data->ul_call_errors,
309 grlc_data->dl_call_errors,
310 grlc_data->rel_type);
311 break;
312 case CGRLC_TBF_MODE_DL:
313 TRACE_EVENT_P4("DL_TBF_REL:nr_of_crc_errors= %ld ul_call_errors=%ld dl_call_errors=%ld rel_type=%d",
314 grlc_data->nr_of_crc_errors,
315 grlc_data->ul_call_errors,
316 grlc_data->dl_call_errors,
317 grlc_data->rel_type);
318 break;
319 case CGRLC_TBF_MODE_DL_UL:
320 TRACE_EVENT_P4("UL/DL_TBF_REL:nr_of_crc_errors= %ld ul_call_errors=%ld dl_call_errors=%ld rel_type=%d",
321 grlc_data->nr_of_crc_errors,
322 grlc_data->ul_call_errors,
323 grlc_data->dl_call_errors,
324 grlc_data->rel_type);
325
326 break;
327 case CGRLC_TBF_MODE_TMA:
328 case CGRLC_TBF_MODE_TMB:
329 TRACE_EVENT_P3 ("Testmode TBF_REL:nr_of_crc_errors= %ld ul_call_errors=%ld dl_call_errors=%ld",
330 grlc_data->nr_of_crc_errors,
331 grlc_data->ul_call_errors,
332 grlc_data->dl_call_errors);
333
334 break;
335
336 }
337 if(grlc_data->ul_call_errors OR grlc_data->dl_call_errors)
338 {
339 TRACE_EVENT_P6("ul_fn_err=%ld,%ld,%ld//dl_fn_err=%ld,%ld,%ld",
340 grlc_data->ul_fn_errors[0],
341 grlc_data->ul_fn_errors[1],
342 grlc_data->ul_fn_errors[2],
343 grlc_data->dl_fn_errors[0],
344 grlc_data->dl_fn_errors[1],
345 grlc_data->dl_fn_errors[2]);
346 grlc_data->ul_call_errors = 0;
347 grlc_data->dl_call_errors = 0;
348 }
349 grlc_data->nr_of_crc_errors = 0;
350 #endif /* defined (_TARGET_) */
351
352 PSEND(hCommGRR,cgrlc_tbf_rel_ind);
353
354 } /* tm_send_tbf_rel() */
355
356
357
358 /*
359 +------------------------------------------------------------------------------
360 | Function : tm_abort_tbf
361 +------------------------------------------------------------------------------
362 | Description : The function tm_abort_tbf() stops a TBF.
363 |
364 | Parameters : tbf_i - TBF type to abort
365 |
366 +------------------------------------------------------------------------------
367 */
368 GLOBAL void tm_abort_tbf ( T_TBF_TYPE tbf_i )
369 {
370 /*SZML-TC/056*/
371
372 TRACE_FUNCTION( "tm_abort_tbf" );
373
374 switch( tbf_i )
375 {
376 case TBF_TYPE_NULL:
377 TRACE_EVENT("NULL TBF active: check if tbf starting time is running");
378 /*SZML-TC/093*/
379 break;
380 #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH
381 case TBF_TYPE_TP_ACCESS:
382 tm_send_tbf_rel(tbf_i);
383 tm_deactivate_tbf(tbf_i);
384 break;
385 #endif
386 case TBF_TYPE_UL:
387 tm_send_tbf_rel(tbf_i);
388 sig_tm_ru_abrel(1, FALSE);
389 tm_deactivate_tbf(tbf_i);
390 break;
391 case TBF_TYPE_DL:
392 tm_send_tbf_rel(tbf_i);
393 sig_tm_rd_abrel(1,FALSE);
394 tm_deactivate_tbf(tbf_i);
395 break;
396 case TBF_TYPE_CONC:
397 tm_send_tbf_rel(tbf_i);
398 sig_tm_ru_abrel(1, FALSE);
399 sig_tm_rd_abrel(1,FALSE);
400 tm_deactivate_tbf(tbf_i);
401 break;
402 default:
403 TRACE_ERROR ( "tm_abort_tbf: TBF type is invalid" );
404 break;
405 }
406 } /* tm_abort_tbf() */
407
408
409
410 /*
411 +------------------------------------------------------------------------------
412 | Function : tm_ini_realloc
413 +------------------------------------------------------------------------------
414 | Description : The function tm_ini_realloc() do all action that are necessary
415 | to start a Resource Re-Allocation Procedure.
416 |
417 | Parameters : void
418 |
419 +------------------------------------------------------------------------------
420 */
421 GLOBAL void tm_ini_realloc ( UBYTE start_of_new_tbf_i )
422 {
423 TRACE_FUNCTION( "tm_ini_realloc" );
424 grlc_data->tm.start_of_new_tbf = start_of_new_tbf_i ;
425
426 /*SZML-TC/058*/
427
428 } /* tm_ini_realloc() */
429
430
431
432 /*
433 +------------------------------------------------------------------------------
434 | Function : tm_build_res_req
435 +------------------------------------------------------------------------------
436 | Description : The function tm_build_res_req() builds Packet Resource Request.
437 |
438 | Parameters : reason_i - the reason for building that packet resouce
439 | reallocation
440 |
441 +------------------------------------------------------------------------------
442 */
443 GLOBAL void tm_build_res_req (T_U_GRLC_RESOURCE_REQ *ptr2res_req,
444 T_REASON_BUILD reason_i)
445 {
446 TRACE_FUNCTION( "tm_build_res_req" );
447
448
449 memset(ptr2res_req,0,sizeof(T_U_GRLC_RESOURCE_REQ) );
450
451
452 /* processing of messsage type */
453 ptr2res_req->msg_type = U_GRLC_RESOURCE_REQ_c;
454
455 /* processing of change mark */
456
457 if( grlc_data->tm.change_mark EQ NOT_SET )
458 {
459 ptr2res_req->v_ma_ch_mark = 0;
460 }
461 else
462 {
463 ptr2res_req->v_ma_ch_mark = 1;
464 ptr2res_req->ma_ch_mark = grlc_data->tm.change_mark;
465 }
466
467 if(reason_i EQ R_FIX_RE_ALLOC)
468 {
469 /* 1 - processing of ACCESS_TYPE */
470 ptr2res_req->v_access_type = 0;
471
472 /* 2 - processing of global TFI and TLLI */
473 ptr2res_req->flag = 0;
474 ptr2res_req->v_glob_tfi = 1;
475 ptr2res_req->glob_tfi.flag = 0;
476 ptr2res_req->glob_tfi.v_ul_tfi = 1;
477 ptr2res_req->glob_tfi.ul_tfi = grlc_data->ul_tfi;
478
479 /* 3 - processing of radio access capabilities */
480 ptr2res_req->v_ra_cap = FALSE;
481
482 /* 4 - processing of channel request description */
483 tm_build_chan_req_des(&ptr2res_req->chan_req_des,
484 &grlc_data->prim_queue[grlc_data->prim_start_tbf]);
485 }
486 else if(reason_i EQ R_RE_ALLOC)
487 {
488 /* 1 - processing of ACCESS_TYPE */
489 ptr2res_req->v_access_type = 0;
490
491 /* 2 - processing of global TFI and TLLI */
492 ptr2res_req->flag = 1;
493 ptr2res_req->v_glob_tfi = 0;
494 ptr2res_req->v_tlli_value = 1;
495
496 grlc_set_buf_tlli( &ptr2res_req->tlli_value, grlc_data->uplink_tbf.tlli );
497
498 /* 3 - processing of radio access capabilities */
499 ptr2res_req->v_ra_cap = FALSE;
500
501 /* 4 - processing of channel request description */
502 tm_build_chan_req_des(&ptr2res_req->chan_req_des,
503 &grlc_data->prim_queue[grlc_data->tm.start_of_new_tbf]);
504 }
505 else if(reason_i EQ R_BUILD_2PHASE_ACCESS)
506 {
507 /* 1 - processing of ACCESS_TYPE */
508 ptr2res_req->v_access_type = 1;
509 ptr2res_req->access_type = TWO_PHASE;
510
511 /* 2 - processing of global TFI and TLLI */
512 ptr2res_req->flag = 1;
513 ptr2res_req->v_glob_tfi = 0;
514 ptr2res_req->v_tlli_value = 1;
515
516 grlc_set_buf_tlli( &ptr2res_req->tlli_value, grlc_data->uplink_tbf.tlli );
517
518 /* 3 - processing of radio access capabilities */
519 if( rr_csf_get_radio_access_capability( &ptr2res_req->ra_cap ) EQ 0 )
520 {
521 ptr2res_req->v_ra_cap = TRUE;
522 }
523 else
524 {
525 ptr2res_req->v_ra_cap = FALSE;
526
527 TRACE_ERROR( "tm_build_res_req: radio access capabilities invalid" );
528 }
529
530 /* 4 - processing of channel request description */
531 tm_build_chan_req_des((T_chan_req_des *)(&ptr2res_req->chan_req_des),
532 &grlc_data->prim_queue[grlc_data->prim_start_tbf] );
533 }
534
535 /* 5 - processing of signal variance */
536 ptr2res_req->signvar = meas_sv_get_value( );
537 ptr2res_req->v_signvar = TRUE;
538
539 /* 6 - processing of relative interference levels */
540 meas_int_get_rel_i_level( &ptr2res_req->ilev );
541
542 /* 7 - processing of C value */
543 ptr2res_req->c_value = meas_grlc_c_get_value( );
544
545 #ifdef REL99
546 ptr2res_req->v_release_99_str_grlc_prr = TRUE;
547
548 /* Workaround to avoid definition of EGPRS measurements info
549 * in grr.aim file. This will reduce the size of ccddata.lib
550 */
551 ptr2res_req->release_99_str_grlc_prr.flag = 0;
552 ptr2res_req->release_99_str_grlc_prr.flag2 = 0;
553
554 /* Flag PFI, shall only include if PFI and BSS R99 */
555 if (grlc_data->nw_rel AND grlc_data->pfi_support)
556 {
557 ptr2res_req->release_99_str_grlc_prr.v_pfi = 1;
558
559 if ( reason_i EQ R_RE_ALLOC )
560 {
561 ptr2res_req->release_99_str_grlc_prr.pfi =
562 grlc_data->prim_queue[grlc_data->tm.start_of_new_tbf].prim_ptr->pkt_flow_id[0];
563 }
564 else
565 {
566 ptr2res_req->release_99_str_grlc_prr.pfi = grlc_data->pfi_value;
567 }
568 }
569 else
570 {
571 ptr2res_req->release_99_str_grlc_prr.v_pfi = 0;
572 }
573
574 ptr2res_req->release_99_str_grlc_prr.add_ms_rac = 0;
575 ptr2res_req->release_99_str_grlc_prr.retrans_of_prr = 0;
576 #endif
577
578
579 } /* tm_build_res_req() */
580
581
582
583
584
585
586
587
588
589
590 /*
591 +------------------------------------------------------------------------------
592 | Function : tm_init_prim
593 +------------------------------------------------------------------------------
594 | Description : The function tm_init_prim() initializes the primitive queue.
595
596 | Parameters : void
597 |
598 +------------------------------------------------------------------------------
599 */
600 GLOBAL void tm_init_prim ( void )
601 {
602 UBYTE i;
603 TRACE_FUNCTION( "tm_init_prim" );
604
605
606 /* LLC PRIM QUEUE*/
607 for (i=0;i<PRIM_QUEUE_SIZE;i++)
608 {
609 /*
610 * set next to the following entry
611 */
612 grlc_data->prim_queue[i].next = i+1;
613
614 /*
615 * and initialize the not used primitive entry
616 */
617 grlc_data->prim_queue[i].prim_ptr = NULL;
618 grlc_data->prim_queue[i].prim_type = CGRLC_LLC_PRIM_TYPE_NULL;
619 grlc_data->prim_queue[i].cv_status = FALSE;
620 grlc_data->prim_queue[i].rlc_status = FALSE;
621 grlc_data->prim_queue[i].re_allocation = FALSE;
622 grlc_data->prim_queue[i].start_new_tbf = FALSE;
623 grlc_data->prim_queue[i].last_bsn = 0xff;
624 }
625
626
627 /*
628 * last free entry points to 0xff
629 */
630 grlc_data->prim_queue[PRIM_QUEUE_SIZE-1].next = 0xff;
631
632 /*
633 * index 0 is the first free entry
634 */
635 grlc_data->prim_start_free = 0;
636
637 /*
638 * becauce there are no primitives in the tbf prim_start_tbf points to 0xff
639 */
640 grlc_data->prim_start_tbf = 0xff;
641
642 /*
643 * init because there are no primitives there is also no user data
644 */
645 grlc_data->prim_user_data = 0;
646
647
648 /* init gmm prim queue*/
649
650 for (i=PRIM_QUEUE_SIZE; i<(PRIM_QUEUE_SIZE_TOTAL);i++)
651 {
652 grlc_data->prim_queue[i].next = i+1;
653
654 grlc_data->prim_queue[i].prim_ptr = NULL;
655 grlc_data->prim_queue[i].prim_type = CGRLC_LLC_PRIM_TYPE_NULL;
656 grlc_data->prim_queue[i].cv_status = FALSE;
657 grlc_data->prim_queue[i].rlc_status = FALSE;
658 grlc_data->prim_queue[i].re_allocation = FALSE;
659 grlc_data->prim_queue[i].start_new_tbf = FALSE;
660 grlc_data->prim_queue[i].last_bsn = 0xff;
661 }
662 grlc_data->gmm_procedure_is_running = FALSE;
663 grlc_data->prim_queue[PRIM_QUEUE_SIZE_TOTAL-1].next = 0xff;
664
665
666
667 } /* tm_init_prim() */
668
669
670
671
672 /*
673 +------------------------------------------------------------------------------
674 | Function : tm_start_access
675 +------------------------------------------------------------------------------
676 | Description : The function tm_start_access() prepares the TC data structure
677 | for a packet access procedure.
678 |
679 | Parameters : void
680 |
681 +------------------------------------------------------------------------------
682 */
683 GLOBAL void tm_start_access ( void )
684 {
685 USHORT rlc_octetts;
686
687 TRACE_FUNCTION( "tm_start_access" );
688
689 /*
690 * mark that first packet access in process
691 */
692
693 grlc_data->tm.n_res_req = 0;
694
695 #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH
696 grlc_data->tm.pacch_prr_pca_sent = FALSE;
697 #endif
698
699
700 grlc_data->tm.n_acc_req_procedures++;
701
702 if(grlc_data->prim_start_tbf < PRIM_QUEUE_SIZE_TOTAL)
703 {
704 grlc_data->uplink_tbf.prio
705 = grlc_data->prim_queue[grlc_data->prim_start_tbf].prim_ptr->radio_prio;
706 /* save prio for packet access request building */
707 rlc_octetts =
708 grlc_data->prim_queue[grlc_data->prim_start_tbf].prim_ptr->sdu.l_buf/8 +1;
709 #ifdef REL99
710 if (grlc_data->pfi_support)
711 {
712 /* pfi will take 1 byte*/
713 grlc_data->uplink_tbf.nr_blocks = ( rlc_octetts / 15 ) + 1;
714 grlc_data->pfi_value =
715 grlc_data->prim_queue[grlc_data->prim_start_tbf].prim_ptr->pkt_flow_id[0];
716 }
717 else
718 #endif
719 { /* last "+1" we need complete bytes/octetts */
720 grlc_data->uplink_tbf.nr_blocks = ( rlc_octetts / 16 ) + 1;
721 }
722
723 /*TRACE_EVENT_P1("tm_start_access: nr_block: %d", grlc_data->uplink_tbf.nr_blocks);*/
724 /* 16 because 23(CS_1 length) -3(blockheader) -4(TLLI) = 16 octetts */
725 /* last "+1" we need complete blocks */
726 if(grlc_data->prim_queue[grlc_data->prim_start_tbf].prim_type EQ CGRLC_LLC_PRIM_TYPE_UNITDATA_REQ )
727 {
728 grlc_data->uplink_tbf.rlc_mode = CGRLC_RLC_MODE_UACK;
729 grlc_data->uplink_tbf.ti = 0; /* mark that contention resolution is not requested */
730 }
731 else
732 {
733 grlc_data->uplink_tbf.rlc_mode = CGRLC_RLC_MODE_ACK;
734 grlc_data->uplink_tbf.ti = 1; /* mark that contention resulution is not yet done */
735 }
736 /*
737 * estimate access_type
738 */
739 if(grlc_data->prim_queue[grlc_data->prim_start_tbf].prim_type EQ CGRLC_LLC_PRIM_TYPE_UNITDATA_REQ )
740 {
741 grlc_data->uplink_tbf.access_type = CGRLC_AT_TWO_PHASE;
742 }
743 else if(grlc_data->uplink_tbf.access_type EQ CGRLC_AT_CELL_UPDATE)
744 {
745 TRACE_EVENT("CU WILL BE PERFORMED");
746 }
747 else
748 {
749 switch(grlc_data->prim_queue[grlc_data->prim_start_tbf].prim_ptr->cause)
750 {
751 case GRLC_DTACS_DEF:
752 if(grlc_data->uplink_tbf.nr_blocks <= 8)
753 {
754 grlc_data->uplink_tbf.access_type = CGRLC_AT_SHORT_ACCESS;
755 }
756 else
757 {
758 grlc_data->uplink_tbf.access_type = CGRLC_AT_ONE_PHASE;
759 }
760 break;
761
762 case GRLC_DTACS_PAGE_RESPONSE:
763 grlc_data->uplink_tbf.access_type = CGRLC_AT_PAGE_RESPONSE;
764 break;
765
766 case GRLC_DTACS_MOBILITY_MANAGEMENT:
767 grlc_data->uplink_tbf.access_type = CGRLC_AT_MM_PROCEDURE;
768 break;
769 case GRLC_DTACS_EMPTY_FRAME:
770 case GRLC_DTACS_CELL_NOTIFI_NULL_FRAME:
771 grlc_data->uplink_tbf.access_type = CGRLC_AT_CELL_UPDATE;
772 TRACE_EVENT("EMPTY FRAME for CU, but not requested by GMM");
773 break;
774
775 default:
776 grlc_data->uplink_tbf.access_type = CGRLC_AT_NULL;
777 break;
778 }
779 }
780 }
781 else
782 {
783 TRACE_ERROR("NO PRIM IN QUEUE in tm_start_access");
784 }
785
786
787 } /* tm_start_access() */
788
789
790
791 /*
792 +------------------------------------------------------------------------------
793 | Function : tm_data_req
794 +------------------------------------------------------------------------------
795 | Description : The function tm_data_req() starts the process of queueing
796 | a primitive received from LLC
797 |
798 | Parameters : prime_tpye_i - primitiven type (PRIME_TYPE_UNITDATA or
799 | PRIME_TYPE_DATA)
800 | ptr2prim_i - address of the primitive to handle
801 |
802 |
803 +------------------------------------------------------------------------------
804 */
805 GLOBAL void tm_data_req ( T_PRIM_TYPE prim_tpye_i,
806 T_GRLC_DATA_REQ * ptr2prim_i)
807 {
808 UBYTE free_entry_count , position , new_prim ;
809 T_COMPARE_PRIM compare_result = C_PRIM_CONTINUE;
810 BOOL new_qos = FALSE;
811
812 TRACE_FUNCTION( "tm_data_req" );
813
814
815 /*
816 * get the index of next free prim queue entry
817 */
818 free_entry_count = tm_prim_queue_get_free_count();
819
820 if (free_entry_count)
821 {
822 /* get first free entry from free list */
823 new_prim = grlc_prim_get_first (&grlc_data->prim_start_free);
824
825 #ifdef REL99
826 /*SM currenlty give 0xFF , in case network does not assign PFI */
827 if (ptr2prim_i->pkt_flow_id[0] EQ 0xFF)
828 {
829 ptr2prim_i->pkt_flow_id[0] = 0;
830 }
831 #endif
832
833 grlc_data->prim_queue[new_prim ].prim_type = prim_tpye_i;
834 grlc_data->prim_queue[new_prim ].prim_ptr = ptr2prim_i;
835
836 position = grlc_data->prim_start_tbf;
837
838 do
839 {
840 if(position < PRIM_QUEUE_SIZE_TOTAL) /* this "if" make sure only valid llc_pdu
841 are used in comparision */
842 {
843
844 compare_result = tm_compare_prim(new_prim ,position ,&new_qos);
845
846 /*
847 * position for new prim is found !
848 */
849 if(compare_result NEQ C_PRIM_CONTINUE) break;
850
851 position = grlc_data->prim_queue[position ].next;
852
853 }
854 else
855 { /* first prim in queue */
856 compare_result = C_PRIM_NEW_TBF;
857 break;
858 }
859
860 } while (1);
861
862
863 switch( compare_result )
864 {
865 case C_PRIM_NEW_TBF:
866 grlc_data->prim_queue[new_prim ].start_new_tbf = 1;
867 break;
868 case C_PRIM_REALLOC_START:
869 {
870 T_U_GRLC_RESOURCE_REQ resource_req;/*lint !e813*/
871
872 tm_ini_realloc(new_prim);
873 tm_build_res_req( &resource_req,
874 R_RE_ALLOC );
875 tm_store_ctrl_blk( CGRLC_BLK_OWNER_TM, ( void* )&resource_req );
876 if (grlc_data->prim_queue[position].next NEQ 0xff)/*sec 8.1.1.1.2 para 10*/
877 {
878 grlc_data->prim_queue[grlc_data->prim_queue[position].next].re_allocation = 1;
879 }
880 }
881 break;
882 case C_PRIM_REALLOC_SHORT:
883 {
884 T_U_GRLC_RESOURCE_REQ resource_req; /*lint !e813*/
885
886 tm_ini_realloc(new_prim);
887 tm_build_res_req( &resource_req,
888 R_FIX_RE_ALLOC );
889 tm_store_ctrl_blk( CGRLC_BLK_OWNER_TM, ( void* )&resource_req );
890 }
891 break;
892
893 case C_PRIM_REALLOC_MARK:
894 grlc_data->prim_queue[new_prim ].re_allocation = 1;
895 break;
896 case C_PRIM_RLC_MODE_CHANGE: /*sec 8.1.1.1.2 para 5*/
897 grlc_data->prim_queue[new_prim].start_new_tbf = 1;
898 grlc_data->prim_queue[grlc_data->prim_queue[position].next].start_new_tbf = 1;
899 break;
900
901 }
902
903
904 if(position < PRIM_QUEUE_SIZE_TOTAL)
905 {
906 position = grlc_data->prim_queue[position].next;
907 }
908 /*This new QOS is for lower priority */
909 if ( (position EQ 0xff) AND (new_qos EQ TRUE))
910 {
911 grlc_data->prim_queue[new_prim].re_allocation = 1;/*8.1.1.1.2 para 10*/
912 TRACE_EVENT_P2("reallocation set for llc pdu = %d ,priority =%d",new_prim,ptr2prim_i->radio_prio);
913 }
914
915 grlc_prim_put(&grlc_data->prim_start_tbf,new_prim ,position );
916
917 /*
918 * update amount of buffered user data
919 */
920 grlc_data->prim_user_data += BYTELEN(ptr2prim_i->sdu.l_buf);
921
922 /*
923 * and check if the queue is now full
924 */
925 free_entry_count--;
926
927 if( (free_entry_count == 0) || (grlc_data->prim_user_data > grlc_data->tm.max_grlc_user_data ) )
928 {
929 grlc_data->tm.send_grlc_ready_ind = PRIM_QUEUE_FULL;
930 }
931 }
932 else
933 {
934 TRACE_ERROR("Data-Request, but prim_queue full");
935 /*
936 * This is an error of LLC.
937 * Therefore here is no special handling of this case
938 */
939 PFREE(ptr2prim_i);
940
941 }
942
943 } /* tm_data_req() */
944
945
946
947 /*
948 +------------------------------------------------------------------------------
949 | Function : tm_grlc_init
950 +------------------------------------------------------------------------------
951 | Description : The function tm_grlc_init() initialize the TC data structure.
952 |
953 | Parameters : void
954 |
955 +------------------------------------------------------------------------------
956 */
957 GLOBAL void tm_grlc_init ( void )
958 {
959 UBYTE i;
960
961 TRACE_FUNCTION( "tm_grlc_init" );
962
963 /*
964 * set some values
965 */
966 grlc_data->tm.disable_class = CGRLC_DISABLE_CLASS_CR;
967 grlc_data->tbf_type = TBF_TYPE_NULL;
968 grlc_data->rel_type = REL_TYPE_NULL;
969 grlc_data->tm.start_of_new_tbf = 0xff;
970 grlc_data->tm.send_grlc_ready_ind = SEND_A_GRLC_READY_IND;
971
972
973 grlc_data->tm.n_acc_req_procedures = 0;
974 grlc_data->tm.n_res_req = 0;
975 #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH
976 grlc_data->tm.pacch_prr_pca_sent = FALSE;
977 #endif
978
979
980 /* initialize the relevant data for uplink control block */
981 grlc_data->tm.ul_ctrl_blk.seq[0] = MAX_CTRL_BLK_NUM;
982
983 for( i = 0; i < MAX_CTRL_BLK_NUM; i++ )
984 {
985 grlc_data->tm.ul_ctrl_blk.blk[i].state = BLK_STATE_NONE;
986 grlc_data->tm.ul_ctrl_blk.blk[i].owner = CGRLC_BLK_OWNER_NONE;
987 }
988
989 /*
990 * Initialise service name (uses define SERVICE_NAME_* in GRLC.H);
991 */
992
993 INIT_STATE(TM,TM_ACCESS_DISABLED);
994 /*
995 * initialize primitive queue
996 */
997 tm_init_prim();
998
999
1000 } /* tm_grlc_init() */
1001
1002
1003
1004
1005 /*
1006 +------------------------------------------------------------------------------
1007 | Function : tm_prim_queue_get_free_count
1008 +------------------------------------------------------------------------------
1009 | Description : This function returns the number of free
1010 | entries in the primitive queue.
1011 |
1012 | Parameters : void
1013 |
1014 +------------------------------------------------------------------------------
1015 */
1016 GLOBAL UBYTE tm_prim_queue_get_free_count ( void )
1017 {
1018 UBYTE i = grlc_data->prim_start_free;
1019 UBYTE result = 0,j;
1020
1021 TRACE_FUNCTION( "tm_prim_queue_get_free_count" );
1022
1023
1024 for(j=0;j<PRIM_QUEUE_SIZE_TOTAL;j++)
1025 {
1026 if (i NEQ 0xff)
1027 {
1028 result++;
1029 i = grlc_data->prim_queue[i].next;
1030 }
1031 else
1032 {
1033 break;
1034 }
1035 }
1036 if((grlc_data->grlc_data_req_cnt + result NEQ PRIM_QUEUE_SIZE )AND
1037 !grlc_data->gmm_procedure_is_running)
1038 {
1039 TRACE_EVENT_P4("PST=%d PSF=%d PDU=%d FREE_CNT=%d: tm_prim_queue_get_free_count CHECK it"
1040 ,grlc_data->prim_start_tbf
1041 ,grlc_data->prim_start_free
1042 ,grlc_data->grlc_data_req_cnt
1043 ,result);
1044 }
1045
1046 return(result);
1047
1048 } /* tm_prim_queue_get_free_count() */
1049
1050
1051
1052
1053 /*
1054 +------------------------------------------------------------------------------
1055 | Function : tm_compare_prim
1056 +------------------------------------------------------------------------------
1057 | Description : The function tm_compare_prim() check wheather the pdu have to
1058 | set at tis position or not. They function also estimate
1059 | how to set this primitive (with new TBF, immediately
1060 | re-allocation or re-allocation at next PDU-boundary)
1061 |
1062 | Parameters : new_prim_i - index of the new-primitive entry in prim_queue[]
1063 | position_i - index of the preceding entry of the possible
1064 | position of the new primitive
1065 +------------------------------------------------------------------------------
1066 */
1067 GLOBAL T_COMPARE_PRIM tm_compare_prim ( UBYTE new_prim_i,
1068 UBYTE position_i,
1069 BOOL *new_qos)
1070 {
1071 BOOL rlc_mode;
1072 UBYTE new_prio = PRIO_HIGHER;
1073 UBYTE new_throughput = THROUGHPUT_HIGHER;
1074 #ifdef REL99
1075 UBYTE new_pfi = SAME_PFI;
1076 #endif
1077 UBYTE pre_prim_index, post_prim_index, new_prim_index;
1078 T_GRLC_UNITDATA_REQ * pre_prim_ptr, * new_prim_ptr, * post_prim_ptr;
1079 T_COMPARE_PRIM result;
1080
1081 TRACE_FUNCTION( "tm_compare_prim" );
1082
1083
1084 /*
1085 * set all variables
1086 */
1087
1088 pre_prim_index = position_i;
1089 post_prim_index = grlc_data->prim_queue[position_i].next;
1090 new_prim_index = new_prim_i;
1091
1092
1093 /*
1094 * GRLC_UNITDATA_REQ and T_GRLC_UNITDATA_REQ have the same layout!!
1095 */
1096 pre_prim_ptr = (T_GRLC_UNITDATA_REQ *) grlc_data->prim_queue[pre_prim_index].prim_ptr;
1097 post_prim_ptr = (T_GRLC_UNITDATA_REQ *) grlc_data->prim_queue[post_prim_index].prim_ptr;
1098 new_prim_ptr = (T_GRLC_UNITDATA_REQ *) grlc_data->prim_queue[new_prim_index].prim_ptr;
1099
1100
1101
1102 if(post_prim_index NEQ 0xff)
1103 {
1104 #ifdef REL99
1105 if (grlc_data->pfi_support AND
1106 (post_prim_ptr->pkt_flow_id[0] NEQ new_prim_ptr->pkt_flow_id[0])
1107 )
1108 {
1109 new_pfi = DIFF_PFI;
1110 }
1111 #endif
1112
1113 /*
1114 * last position in queue; the values at position 0xff in the prim_queue are invalid
1115 * therefore they are here not set
1116 */
1117 if(post_prim_ptr->radio_prio < new_prim_ptr->radio_prio )
1118 {
1119 new_prio = PRIO_LOWER;
1120 }
1121 else if(post_prim_ptr->radio_prio EQ new_prim_ptr->radio_prio )
1122 {
1123 new_prio = PRIO_SAME;
1124 }
1125
1126 if(post_prim_ptr->grlc_qos.peak > new_prim_ptr->grlc_qos.peak )
1127 {
1128 new_throughput = THROUGHPUT_LOWER;
1129 }
1130 else if(post_prim_ptr->grlc_qos.peak EQ new_prim_ptr->grlc_qos.peak )
1131 {
1132 new_throughput = THROUGHPUT_SAME;
1133 }
1134 }
1135
1136 /* TRACE_EVENT_P2("np=%d np=%d",new_prio,new_throughput);*/
1137
1138
1139 /*
1140 * evalute - wheather the primitive have to put at this position or not
1141 * compare with "following primitive"
1142 */
1143
1144
1145 if(post_prim_index EQ 0xff)
1146 { /*
1147 * because this is the last entry in prim_queue this
1148 * primitive have to put at this position
1149 */
1150 result = C_PRIM_PUT;
1151 }
1152 else
1153 {
1154 if (grlc_data->prim_queue[post_prim_index].rlc_status)
1155 { /*
1156 * it is forbidden to change position of
1157 * primitives already in transmission
1158 */
1159 result = C_PRIM_CONTINUE;
1160 }
1161 else if (grlc_data->prim_queue[post_prim_index].cv_status)
1162 {/*
1163 * it is forbidden to change position of primitives
1164 * included in countdown procedure
1165 */
1166 result = C_PRIM_CONTINUE;
1167 }
1168 #ifdef REL99
1169 else if (new_pfi EQ DIFF_PFI)
1170 {
1171 result = C_PRIM_PUT;
1172 }
1173 #endif
1174 else if ( new_prio EQ PRIO_HIGHER)
1175 {
1176 result = C_PRIM_PUT;
1177 }
1178 else if ( (new_prio EQ PRIO_SAME) AND (new_throughput EQ THROUGHPUT_HIGHER) )
1179 {
1180 result = C_PRIM_PUT;
1181 }
1182 else
1183 {
1184 result = C_PRIM_CONTINUE;
1185 }
1186 }
1187
1188 /*
1189 * evalute - type of "put"
1190 * compare with "preceding primitive"
1191 */
1192
1193
1194 /*TRACE_EVENT_P3("np=%d np=%d result=%d",new_prio,new_throughput,result);*/
1195
1196
1197 if(result EQ C_PRIM_PUT)
1198 {
1199
1200 /*
1201 * set variables
1202 */
1203
1204
1205 if(pre_prim_ptr->radio_prio < new_prim_ptr->radio_prio )
1206 {
1207 new_prio = PRIO_LOWER;
1208 *new_qos = TRUE;
1209 }
1210 else if(pre_prim_ptr->radio_prio EQ new_prim_ptr->radio_prio )
1211 {
1212 new_prio = PRIO_SAME;
1213 }
1214 else
1215 {
1216 new_prio = PRIO_HIGHER;
1217 }
1218
1219 if(pre_prim_ptr->grlc_qos.peak > new_prim_ptr->grlc_qos.peak )
1220 {
1221 new_throughput = THROUGHPUT_LOWER;
1222 }
1223 else if(pre_prim_ptr->grlc_qos.peak EQ new_prim_ptr->grlc_qos.peak )
1224 {
1225 new_throughput = THROUGHPUT_SAME;
1226 }
1227 else
1228 {
1229 new_throughput = THROUGHPUT_HIGHER;
1230 }
1231
1232 #ifdef REL99
1233 if (grlc_data->pfi_support AND
1234 (pre_prim_ptr->pkt_flow_id[0] NEQ new_prim_ptr->pkt_flow_id[0])
1235 )
1236 {
1237 new_pfi = DIFF_PFI;
1238 }
1239 else
1240 {
1241 new_pfi = SAME_PFI;
1242 }
1243 #endif
1244
1245 if ( grlc_data->prim_queue[pre_prim_index].prim_type EQ
1246 grlc_data->prim_queue[new_prim_index].prim_type)
1247 {
1248 rlc_mode = SAME_RLC_MODE;
1249 }
1250 else
1251 {
1252 rlc_mode = DIFFERENT_RLC_MODE;
1253 }
1254
1255
1256
1257
1258
1259 /*
1260 * evalution
1261 */
1262
1263
1264 /* TRACE_EVENT_P4("result=%d,rlc_mode=%d,prio=%d,peak=%d",result,rlc_mode,new_prio,new_throughput);*/
1265
1266 if(rlc_mode EQ DIFFERENT_RLC_MODE)
1267 {
1268
1269 if (new_prio EQ PRIO_HIGHER AND post_prim_index NEQ 0xFF)
1270 {
1271 result = C_PRIM_RLC_MODE_CHANGE;
1272 }
1273 else
1274 {
1275 result = C_PRIM_NEW_TBF;
1276 }
1277 }
1278 else if (grlc_data->prim_queue[pre_prim_index].cv_status)
1279 { /*
1280 * if count-down-procedure has started for this pdu,
1281 * re-allocation is forbitten
1282 */
1283 result = C_PRIM_NEW_TBF;
1284 }
1285 #ifdef REL99
1286 else if ( grlc_data->pfi_support AND
1287 grlc_data->prim_queue[pre_prim_index].rlc_status AND
1288 new_pfi EQ DIFF_PFI
1289 )
1290 {
1291 result = C_PRIM_REALLOC_START;
1292 TRACE_EVENT_P3("C_PRIM_REALLOC_START: npfi = %d, rlc_st = %d pre_prim_i=%d"
1293 ,new_prim_ptr->pkt_flow_id[0]
1294 ,grlc_data->prim_queue[pre_prim_index].rlc_status
1295 ,pre_prim_index);
1296
1297 }
1298 #endif
1299 else if( (grlc_data->prim_queue[pre_prim_index].rlc_status) AND
1300 ((new_prio EQ PRIO_HIGHER ) OR
1301 ((new_throughput EQ THROUGHPUT_HIGHER ) AND (new_prio EQ PRIO_SAME ))
1302 )
1303 )
1304 { /*
1305 * C_PRIM_REALLOC_START only if the "pre-pdu"
1306 * is in transmission
1307 */
1308 TRACE_EVENT_P4("C_PRIM_REALLOC_START: ntp=%d np=%d rlc_st=%d pre_prim_i=%d"
1309 ,new_throughput
1310 ,new_prio
1311 ,grlc_data->prim_queue[pre_prim_index].rlc_status
1312 ,pre_prim_index);
1313 result = C_PRIM_REALLOC_START;
1314 }
1315 else if(
1316 (new_prio EQ PRIO_LOWER ) OR
1317 ((new_throughput EQ THROUGHPUT_LOWER ) AND (new_prio EQ PRIO_SAME ))
1318 )
1319
1320 {
1321 result = C_PRIM_REALLOC_MARK;
1322 TRACE_EVENT_P4("C_PRIM_REALLOC_MARK: ntp=%d np=%d rlc_st=%d pre_prim_i=%d"
1323 ,new_throughput
1324 ,new_prio
1325 ,grlc_data->prim_queue[pre_prim_index].rlc_status
1326 ,pre_prim_index);
1327 }
1328 else if (grlc_data->uplink_tbf.ac_class >= CGRLC_PCCCH_AC_NOT_ALLOWED AND /* if pbcch is present */
1329 grlc_data->uplink_tbf.access_type EQ CGRLC_AT_SHORT_ACCESS AND /* last acess type */
1330 grlc_data->tbf_type NEQ TBF_TYPE_DL) /* not required if acess is over existing downlink tbf*/
1331 {
1332 /* if prevoious access type is short access, ms should send packet resource request*/
1333 result = C_PRIM_REALLOC_SHORT;
1334 grlc_data->uplink_tbf.access_type = CGRLC_AT_ONE_PHASE;
1335 TRACE_EVENT_P4("C_PRIM_REALLOC_SHORT: ntp=%d np=%d rlc_st=%d pre_prim_i=%d"
1336 ,new_throughput
1337 ,new_prio
1338 ,grlc_data->prim_queue[pre_prim_index].rlc_status
1339 ,pre_prim_index);
1340
1341 }
1342 }
1343
1344 /* TRACE_EVENT_P4("np=%d np=%d rlc_mode=%d result=%d",new_prio,new_throughput,rlc_mode,result);*/
1345
1346
1347 return(result);
1348
1349 } /* tm_compare_prim() */
1350
1351
1352
1353 /*
1354 +------------------------------------------------------------------------------
1355 | Function : tm_send_grlc_ready_ind
1356 +------------------------------------------------------------------------------
1357 | Description : This function sends the GRLC_READY_IND
1358 |
1359 | Parameters :
1360 |
1361 +------------------------------------------------------------------------------
1362 */
1363 LOCAL void tm_send_grlc_ready_ind ( void )
1364 {
1365 if(grlc_data->gmm_procedure_is_running)
1366 {
1367 PALLOC(grlc_suspend_ready_ind, GRLC_SUSPEND_READY_IND);
1368 PSEND(hCommLLC, grlc_suspend_ready_ind);
1369 }
1370 else
1371 {
1372 PALLOC(grlc_ready_ind, GRLC_READY_IND);
1373 PSEND(hCommLLC, grlc_ready_ind);
1374 }
1375 } /* tm_send_grlc_ready_ind() */
1376
1377 /*
1378 +------------------------------------------------------------------------------
1379 | Function : tm_handle_grlc_ready_ind
1380 +------------------------------------------------------------------------------
1381 | Description : This function handles the sending of the GRLC_READY_IND. Call
1382 | to this function in any of the following cases:
1383 |
1384 | - a GRLC_DATA_REQ was received
1385 | - a GRLC_UNITDATA_REQ was received
1386 | - a queued prim is deleted
1387 | - the TM state is changed from TM_ACCESS_DISABLED or
1388 | TM_ACCESS_PREPARED to another
1389 |
1390 | Parameters : none
1391 +------------------------------------------------------------------------------
1392 */
1393 GLOBAL void tm_handle_grlc_ready_ind ( void )
1394 {
1395 UBYTE state = GET_STATE( TM );
1396
1397 TRACE_FUNCTION( "tm_handle_grlc_ready_ind" );
1398
1399 if( state EQ TM_ACCESS_DISABLED OR
1400 state EQ TM_ACCESS_PREPARED )
1401 {
1402 TRACE_EVENT("TM_ACCESS_DISABLED/TM_ACCESS_PREPARED no ready ind");
1403 return;
1404 }
1405
1406 switch (grlc_data->tm.send_grlc_ready_ind)
1407 {
1408 case SEND_A_GRLC_READY_IND:
1409 tm_send_grlc_ready_ind();
1410 grlc_data->tm.send_grlc_ready_ind = WAIT_FOR_LLC_DATA_REQ;
1411 break;
1412
1413 case PRIM_QUEUE_FULL:
1414 /*
1415 * Check if we have now enough space
1416 */
1417 TRACE_EVENT_P3("PRIM_QUEUE_FULL prim_start_tbf=%d prim_start_free=%ld user_data=%ld",
1418 grlc_data->prim_start_tbf,
1419 grlc_data->prim_start_free,
1420 grlc_data->prim_user_data);
1421 if ( (tm_prim_queue_get_free_count() > 0) AND
1422 (grlc_data->prim_user_data <= grlc_data->tm.max_grlc_user_data) )
1423 {
1424 TRACE_EVENT("NOT PRIM_QUEUE_FULL !!!");
1425 tm_send_grlc_ready_ind();
1426 grlc_data->tm.send_grlc_ready_ind = WAIT_FOR_LLC_DATA_REQ;
1427 }
1428 break;
1429
1430 case WAIT_FOR_LLC_DATA_REQ:
1431 /* NO BREAK */
1432 default:
1433 /* Nothing to do */
1434 break;
1435 }
1436
1437 } /* tm_handle_grlc_ready_ind() */
1438
1439
1440
1441 /*
1442 +------------------------------------------------------------------------------
1443 | Function : tm_handle_error_ra
1444 +------------------------------------------------------------------------------
1445 | Description : The function tm_handle_error_ra() handles actions related
1446 | to errors that leads to randam access procedure
1447 |
1448 | Parameters : void
1449 |
1450 +------------------------------------------------------------------------------
1451 */
1452 GLOBAL void tm_handle_error_ra ( void )
1453 {
1454 TRACE_FUNCTION( "tm_handle_error_ra" );
1455
1456
1457 /*
1458 * - called in case of contention resulution failed in RU
1459 * - t3168 expires contention resulution failed in 2P-Access
1460 * - If the mobile station has been assigned more PDCHs than it supports according
1461 * to its MS multislot class, the mobile station shall reinitiate the packet access
1462 * procedure unless it has already been repeated 4 times. In that
1463 * case, TBF failure has occurred.
1464 */
1465
1466
1467 /*
1468 * Kill TBF if running
1469 */
1470
1471 TRACE_EVENT_P3("ERROR_RA: nacc: %d prim_start_tbf:%d t3164_cnt=%d"
1472 ,grlc_data->tm.n_acc_req_procedures
1473 ,grlc_data->prim_start_tbf
1474 ,grlc_data->t3164_to_cnt);
1475
1476 if(grlc_data->tbf_type NEQ CGRLC_TBF_MODE_NULL)
1477 {
1478 SET_STATE(TM,TM_WAIT_4_PIM);
1479 }
1480 else
1481 {
1482 SET_STATE(TM,TM_PIM);
1483 sig_tm_ru_reset_poll_array();
1484 }
1485
1486 tm_abort_tbf(grlc_data->tbf_type);
1487 grlc_data->tm.n_res_req = 0; /* reset counter of resource requests during access */
1488
1489 if (grlc_data->N3102 EQ 0)
1490 {
1491 }
1492 else if((grlc_data->tm.n_acc_req_procedures < 5) AND
1493 (grlc_data->t3164_to_cnt < 4))
1494 {
1495 }
1496 else
1497 {
1498 grlc_data->t3164_to_cnt = 0;
1499 grlc_data->tm.n_acc_req_procedures = 0;
1500 tm_cgrlc_status_ind(CGRLC_TBF_ESTABLISHMENT_FAILURE);
1501 grlc_delete_prim();
1502 tm_handle_grlc_ready_ind();
1503 }
1504
1505
1506
1507 } /* tm_handle_error_ra() */
1508
1509 /*
1510 +------------------------------------------------------------------------------
1511 | Function : tm_activate_tbf
1512 +------------------------------------------------------------------------------
1513 | Description : The function tm_activate_tbf() set the assigned TBF
1514 | into the data structures
1515 |
1516 | Parameters : tbf_type_i - type of TBF to deactivate
1517 |
1518 +------------------------------------------------------------------------------
1519 */
1520 GLOBAL void tm_activate_tbf ( T_TBF_TYPE tbf_type_i )
1521 {
1522 TRACE_FUNCTION( "tm_activate_tbf" );
1523
1524 /*
1525 * Reset of n_acc_req_procedures because of the fact that number of
1526 * access procedures during pacet access procedures must not considered in
1527 * a error with random access occured during running TBF.
1528 */
1529 /* grlc_data->tm.n_acc_req_procedures = 0;*/
1530
1531 switch( tbf_type_i )
1532 {
1533 case TBF_TYPE_UL:
1534 switch( grlc_data->tbf_type )
1535 {
1536 case TBF_TYPE_DL:
1537 grlc_data->tbf_type = TBF_TYPE_CONC;
1538 break;
1539 case TBF_TYPE_NULL:
1540 #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH
1541 case TBF_TYPE_TP_ACCESS:
1542 #endif
1543 grlc_data->tbf_type = TBF_TYPE_UL;
1544 break;
1545 default:
1546 break;
1547 }
1548 break;
1549 case TBF_TYPE_DL:
1550 switch( grlc_data->tbf_type )
1551 {
1552 case TBF_TYPE_UL:
1553 grlc_data->tbf_type = TBF_TYPE_CONC;
1554 break;
1555 case TBF_TYPE_NULL:
1556 grlc_data->tbf_type = TBF_TYPE_DL;
1557 break;
1558 default:
1559 break;
1560 }
1561 break;
1562 case TBF_TYPE_CONC:
1563 switch( grlc_data->tbf_type )
1564 {
1565 case TBF_TYPE_UL:
1566 case TBF_TYPE_DL:
1567 case TBF_TYPE_CONC:
1568 grlc_data->tbf_type = TBF_TYPE_CONC;
1569 break;
1570 default:
1571 {
1572 TRACE_ERROR("FATAL ERROR: tm_activate_tbf called with wrong tbf_type");
1573 }
1574 break;
1575 }
1576 break;
1577 #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH
1578 case TBF_TYPE_TP_ACCESS:
1579 switch( grlc_data->tbf_type )
1580 {
1581 case TBF_TYPE_NULL:
1582 grlc_data->tbf_type = TBF_TYPE_TP_ACCESS;
1583 break;
1584 default:
1585 {
1586 TRACE_ERROR("FATAL ERROR: tm_activate_tbf called with wrong tbf_type");
1587 }
1588 break;
1589 }
1590 break;
1591 #endif
1592 default:
1593 {
1594 TRACE_ERROR("FATAL ERROR: tm_activate_tbf called with wrong tbf_type");
1595 }
1596 break;
1597 } /* switch (tbf_type_i) */
1598
1599
1600 } /* tm_activate_tbf() */
1601
1602
1603 /*
1604 +------------------------------------------------------------------------------
1605 | Function : tm_deactivate_tbf
1606 +------------------------------------------------------------------------------
1607 | Description : The function tm_deactivate_tbf() removes a TBF logical from TM
1608 | end estimates how to continue.
1609 |
1610 | Parameters : void
1611 |
1612 +------------------------------------------------------------------------------
1613 */
1614 GLOBAL void tm_deactivate_tbf ( T_TBF_TYPE tbf_i )
1615 {
1616 TRACE_FUNCTION( "tm_deactivate_tbf" );
1617
1618 switch( grlc_data->tbf_type )
1619 {
1620
1621 case TBF_TYPE_CONC:
1622 switch( tbf_i )
1623 {
1624 case TBF_TYPE_UL:
1625 grlc_data->tbf_type = TBF_TYPE_DL;
1626 break;
1627 case TBF_TYPE_DL:
1628 grlc_data->tbf_type = TBF_TYPE_UL;
1629 break;
1630 case TBF_TYPE_CONC:
1631 grlc_data->tbf_type = TBF_TYPE_NULL;
1632 break;
1633 }
1634 break;
1635
1636
1637
1638 case TBF_TYPE_DL:
1639 case TBF_TYPE_UL:
1640 if(grlc_data->tbf_type EQ tbf_i)
1641 {
1642 grlc_data->tbf_type = TBF_TYPE_NULL;
1643 }
1644 else
1645 {
1646 TRACE_ERROR("requested release tbf type does not exist");
1647 TRACE_EVENT_P2("SNH: requested release tbf type does not exist tbf_i =%d tbf_ty=%d",tbf_i,grlc_data->tbf_type);
1648 }
1649 break;
1650 #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH
1651 case TBF_TYPE_TP_ACCESS:
1652 grlc_data->tbf_type = TBF_TYPE_NULL;
1653 break;
1654 #endif
1655 default:
1656 break;
1657 }
1658
1659 } /* tm_deactivate_tbf() */
1660
1661
1662
1663
1664
1665
1666 /*
1667 +------------------------------------------------------------------------------
1668 | Function : tm_delete_prim_queue
1669 +------------------------------------------------------------------------------
1670 | Description : delete all pdus in the queue
1671 |
1672 | Parameters : void
1673 |
1674 +------------------------------------------------------------------------------
1675 */
1676 GLOBAL void tm_delete_prim_queue( void)
1677 {
1678 TRACE_FUNCTION( "tm_delete_prim_queue" );
1679
1680 do
1681 {
1682 grlc_delete_prim();
1683
1684 } while( (grlc_data->prim_start_tbf < PRIM_QUEUE_SIZE_TOTAL) AND
1685 !grlc_data->prim_queue[grlc_data->prim_start_tbf].start_new_tbf );
1686
1687 tm_handle_grlc_ready_ind();
1688
1689 } /* tm_delete_prim_queue */
1690
1691
1692
1693
1694
1695 /*
1696 +------------------------------------------------------------------------------
1697 | Function : tm_queue_test_mode_prim()
1698 +------------------------------------------------------------------------------
1699 | Description : The function puts a number of primitives
1700 | in the primitive queue
1701 |
1702 | Parameters : pdu_num_i - number of primitives to queue
1703 |
1704 +------------------------------------------------------------------------------
1705 */
1706 GLOBAL void tm_queue_test_mode_prim( UBYTE pdu_num_i )
1707 {
1708 UBYTE i = 0;
1709 TRACE_FUNCTION( "tm_queue_test_mode_prim" );
1710
1711
1712 for (i=0; i<pdu_num_i; i++)
1713 {
1714 PALLOC_SDU(grlc_unitdata_req,GRLC_UNITDATA_REQ,(195*8));
1715 grlc_unitdata_req->sapi = GRLC_SAPI_TEST_MODE;
1716 grlc_unitdata_req->tlli = grlc_data->uplink_tbf.tlli;
1717 memset(&grlc_unitdata_req->grlc_qos,0,sizeof(T_GRLC_grlc_qos));
1718 grlc_unitdata_req->radio_prio=2;
1719 grlc_unitdata_req->sdu.l_buf= 195*8;
1720 grlc_unitdata_req->sdu.o_buf=0;
1721 memset(grlc_unitdata_req->sdu.buf,0x0f,195); /*lint !e419*/
1722 PSEND(hCommGRLC,grlc_unitdata_req);
1723 }
1724
1725 } /* tm_queue_test_mode_prim */
1726
1727
1728
1729 /*
1730 +------------------------------------------------------------------------------
1731 | Function : tm_close_gaps_in_ctrl_blk_seq
1732 +------------------------------------------------------------------------------
1733 | Description : The function tm_close_gaps_in_ctrl_blk_seq reorders the queue
1734 | holding the order which is used to identify the next control
1735 | block to sent.
1736 |
1737 | Parameters : index - at this index the reordering starts
1738 |
1739 +------------------------------------------------------------------------------
1740 */
1741 LOCAL void tm_close_gaps_in_ctrl_blk_seq ( UBYTE index )
1742 {
1743 TRACE_FUNCTION( "tm_close_gaps_in_ctrl_blk_seq" );
1744
1745 while( index < MAX_CTRL_BLK_NUM AND
1746 grlc_data->tm.ul_ctrl_blk.seq[index] NEQ MAX_CTRL_BLK_NUM )
1747 {
1748 grlc_data->tm.ul_ctrl_blk.seq[index-1] = grlc_data->tm.ul_ctrl_blk.seq[index];
1749
1750 index++;
1751 }
1752
1753 grlc_data->tm.ul_ctrl_blk.seq[index-1] = MAX_CTRL_BLK_NUM;
1754
1755 } /* tm_close_gaps_in_ctrl_blk_seq() */
1756
1757 /*
1758 +------------------------------------------------------------------------------
1759 | Function : tm_store_ctrl_blk
1760 +------------------------------------------------------------------------------
1761 | Description :
1762 |
1763 | Parameters :
1764 |
1765 +------------------------------------------------------------------------------
1766 */
1767 GLOBAL BOOL tm_store_ctrl_blk ( T_BLK_OWNER blk_owner, void *blk_struct )
1768 {
1769 UBYTE i; /* used for counting */
1770 BOOL result = FALSE; /* indicates whether control block is */
1771 /* stored successfully or not */
1772 T_BLK_INDEX blk_index; /* index to the control block buffer */
1773
1774 TRACE_FUNCTION( "tm_store_ctrl_msg" );
1775
1776 /*
1777 * we have to find a free buffer for the control block which is
1778 * indicated by the index to the control block buffer
1779 */
1780 blk_index = MAX_CTRL_BLK_NUM;
1781
1782 switch( blk_owner )
1783 {
1784 case( CGRLC_BLK_OWNER_CTRL ):
1785 if( grlc_data->tm.ul_ctrl_blk.blk[BLK_INDEX_CTRL].state EQ BLK_STATE_NONE )
1786 {
1787 blk_index = BLK_INDEX_CTRL;
1788 }
1789 break;
1790
1791 case( CGRLC_BLK_OWNER_CS ):
1792 if( grlc_data->tm.ul_ctrl_blk.blk[BLK_INDEX_CS].state EQ BLK_STATE_NONE )
1793 {
1794 blk_index = BLK_INDEX_CS;
1795 }
1796 break;
1797
1798 case( CGRLC_BLK_OWNER_TM ):
1799 if( grlc_data->tm.ul_ctrl_blk.blk[BLK_INDEX_TM].state EQ BLK_STATE_NONE )
1800 {
1801 blk_index = BLK_INDEX_TM;
1802 }
1803 break;
1804
1805 case( CGRLC_BLK_OWNER_MEAS ):
1806
1807 blk_index = BLK_INDEX_MEAS;
1808
1809 while( blk_index < MAX_CTRL_BLK_NUM AND
1810 grlc_data->tm.ul_ctrl_blk.blk[blk_index].state NEQ BLK_STATE_NONE )
1811 {
1812 blk_index++;
1813 }
1814 break;
1815
1816 default:
1817 /* do nothing */
1818 break;
1819 }
1820
1821 /*
1822 * check whether the control block buffer is free,
1823 */
1824 if( blk_index < MAX_CTRL_BLK_NUM )
1825 {
1826 /*
1827 * check the queue holding the order which is used to identify the next
1828 * control block to send
1829 */
1830 i = 0;
1831
1832 while( i < MAX_CTRL_BLK_NUM AND
1833 grlc_data->tm.ul_ctrl_blk.seq[i] NEQ MAX_CTRL_BLK_NUM )
1834 {
1835 i++;
1836 }
1837
1838 /*
1839 * check whether there is a free entry in the order queue,
1840 * in case the check fails, there is something wrong with the concept
1841 */
1842 if( i < MAX_CTRL_BLK_NUM )
1843 {
1844 /*
1845 * store the control block data and state in the queues
1846 */
1847 if(blk_owner EQ CGRLC_BLK_OWNER_TM)
1848 {
1849 grlc_encode_ul_ctrl_block
1850 ( ( UBYTE* )&grlc_data->tm.ul_ctrl_blk.blk[blk_index].data[0],
1851 ( UBYTE* )blk_struct );
1852 }
1853 else
1854 {
1855 /*
1856 * encoded control message received by higher layers
1857 */
1858 memcpy(( UBYTE* )&grlc_data->tm.ul_ctrl_blk.blk[blk_index].data[0],( UBYTE* )blk_struct,BYTE_UL_CTRL_BLOCK);
1859 }
1860
1861 grlc_data->tm.ul_ctrl_blk.blk[blk_index].state = BLK_STATE_ALLOCATED;
1862 grlc_data->tm.ul_ctrl_blk.blk[blk_index].owner = blk_owner;
1863 grlc_data->tm.ul_ctrl_blk.seq[i] = blk_index;
1864
1865 if( i < MAX_CTRL_BLK_NUM - 1 )
1866 {
1867 grlc_data->tm.ul_ctrl_blk.seq[i+1] = MAX_CTRL_BLK_NUM;
1868 }
1869
1870 result = TRUE;
1871 }
1872 else
1873 {
1874 TRACE_ERROR( "tm_store_ctrl_blk: no free entry in queue found" );
1875 }
1876 }
1877
1878 if( result EQ FALSE )
1879 {
1880 if( blk_owner EQ CGRLC_BLK_OWNER_MEAS )
1881 {
1882 TRACE_EVENT( "tm_store_ctrl_blk: no table entry allocated" );
1883 }
1884 else
1885 {
1886 TRACE_ERROR( "tm_store_ctrl_blk: no table entry allocated" );
1887 }
1888 }
1889
1890 return( result );
1891
1892 } /* tm_store_ctrl_blk() */
1893
1894 /*
1895 +------------------------------------------------------------------------------
1896 | Function : tm_cancel_ctrl_blk
1897 +------------------------------------------------------------------------------
1898 | Description :
1899 |
1900 | Parameters :
1901 |
1902 +------------------------------------------------------------------------------
1903 */
1904 GLOBAL BOOL tm_cancel_ctrl_blk ( T_BLK_OWNER blk_owner )
1905 {
1906 BOOL result = FALSE;
1907 UBYTE i = 0;
1908 UBYTE blk_index = grlc_data->tm.ul_ctrl_blk.seq[i];
1909
1910 TRACE_FUNCTION( "tm_cancel_ctrl_blk" );
1911
1912
1913 while( blk_index NEQ MAX_CTRL_BLK_NUM AND
1914 result EQ FALSE )
1915 {
1916 if( grlc_data->tm.ul_ctrl_blk.blk[blk_index].owner EQ blk_owner AND
1917 grlc_data->tm.ul_ctrl_blk.blk[blk_index].state EQ BLK_STATE_ALLOCATED )
1918 {
1919 /*
1920 * mark the entry in the queue as free
1921 */
1922 grlc_data->tm.ul_ctrl_blk.blk[blk_index].state = BLK_STATE_NONE;
1923 grlc_data->tm.ul_ctrl_blk.blk[blk_index].owner = CGRLC_BLK_OWNER_NONE;
1924
1925 tm_close_gaps_in_ctrl_blk_seq( (UBYTE)( i + 1 ) );
1926
1927 result = TRUE;
1928 }
1929
1930 i++;
1931 if( i < MAX_CTRL_BLK_NUM )
1932 {
1933 blk_index = grlc_data->tm.ul_ctrl_blk.seq[i];
1934 }
1935 else
1936 {
1937 blk_index = MAX_CTRL_BLK_NUM;
1938 }
1939 }
1940
1941 if( result EQ FALSE )
1942 {
1943 TRACE_EVENT( "tm_cancel_ctrl_blk: no block found" );
1944 }
1945
1946 return( result );
1947
1948 } /* tm_cancel_ctrl_blk() */
1949
1950 /*
1951 +------------------------------------------------------------------------------
1952 | Function : tm_set_start_ctrl_blk
1953 +------------------------------------------------------------------------------
1954 | Description :
1955 |
1956 | Parameters :
1957 |
1958 +------------------------------------------------------------------------------
1959 */
1960 GLOBAL UBYTE* tm_set_start_ctrl_blk ( UBYTE *index )
1961 {
1962 UBYTE i = 0;
1963 T_BLK_INDEX blk_index = MAX_CTRL_BLK_NUM;
1964
1965 TRACE_FUNCTION( "tm_set_start_ctrl_blk" );
1966
1967 while( i < MAX_CTRL_BLK_NUM AND
1968 grlc_data->tm.ul_ctrl_blk.seq[i] NEQ MAX_CTRL_BLK_NUM AND
1969 blk_index EQ MAX_CTRL_BLK_NUM )
1970 {
1971 blk_index = grlc_data->tm.ul_ctrl_blk.seq[i];
1972
1973 if( grlc_data->tm.ul_ctrl_blk.blk[blk_index].state EQ BLK_STATE_ALLOCATED )
1974 {
1975 grlc_data->tm.ul_ctrl_blk.blk[blk_index].state = BLK_STATE_SENT_REQ;
1976
1977 /*
1978 * the control block was encoded without having correct information
1979 * about the value of the R bit. So we have to set the correct value now.
1980 */
1981 grlc_data->tm.ul_ctrl_blk.blk[blk_index].data[0] = 0x40 | grlc_data->r_bit;
1982 }
1983 else
1984 {
1985 blk_index = MAX_CTRL_BLK_NUM;
1986 }
1987
1988 i++;
1989 }
1990
1991 *index = blk_index;
1992
1993 return( blk_index EQ MAX_CTRL_BLK_NUM ?
1994 NULL : grlc_data->tm.ul_ctrl_blk.blk[blk_index].data );
1995
1996 } /* tm_set_start_ctrl_blk() */
1997
1998 /*
1999 +------------------------------------------------------------------------------
2000 | Function : tm_set_stop_ctrl_blk
2001 +------------------------------------------------------------------------------
2002 | Description :
2003 |
2004 | Parameters :
2005 |
2006 +------------------------------------------------------------------------------
2007 */
2008 GLOBAL T_BLK_INDEX tm_set_stop_ctrl_blk
2009 ( BOOL is_tx_success, T_BLK_OWNER srch_owner, T_BLK_INDEX start_index )
2010 {
2011 T_BLK_INDEX blk_index = grlc_data->tm.ul_ctrl_blk.seq[start_index];
2012 T_BLK_INDEX nxt_index;
2013
2014 TRACE_FUNCTION( "tm_set_stop_ctrl_blk" );
2015
2016 if( blk_index < MAX_CTRL_BLK_NUM )
2017 {
2018 T_BLK_OWNER blk_owner = grlc_data->tm.ul_ctrl_blk.blk[blk_index].owner;
2019
2020 if( srch_owner EQ CGRLC_BLK_OWNER_NONE OR
2021 srch_owner EQ blk_owner )
2022 {
2023 /*
2024 * mark the entry in the queue as free
2025 */
2026 grlc_data->tm.ul_ctrl_blk.blk[blk_index].state = BLK_STATE_NONE;
2027 grlc_data->tm.ul_ctrl_blk.blk[blk_index].owner = CGRLC_BLK_OWNER_NONE;
2028
2029 tm_close_gaps_in_ctrl_blk_seq( 1 );
2030
2031 nxt_index = start_index;
2032 }
2033 else
2034 {
2035 nxt_index = start_index + 1;
2036 }
2037 }
2038 else
2039 {
2040 nxt_index = MAX_CTRL_BLK_NUM;
2041 }
2042
2043 return( nxt_index );
2044
2045 } /* tm_set_stop_ctrl_blk() */
2046
2047 /*
2048 +------------------------------------------------------------------------------
2049 | Function : tm_set_stop_tm_ctrl_blk
2050 +------------------------------------------------------------------------------
2051 | Description :
2052 |
2053 | Parameters :
2054 |
2055 +------------------------------------------------------------------------------
2056 */
2057 GLOBAL void tm_set_stop_tm_ctrl_blk ( void )
2058 {
2059 T_BLK_INDEX start_index = 0;
2060
2061 TRACE_FUNCTION( "tm_set_stop_tm_ctrl_blk" );
2062
2063 while
2064 (
2065 ( start_index = tm_set_stop_ctrl_blk( FALSE, CGRLC_BLK_OWNER_TM, start_index ) )
2066 NEQ MAX_CTRL_BLK_NUM
2067 ){};
2068 } /* tm_set_stop_tm_ctrl_blk() */
2069
2070 /*
2071 +------------------------------------------------------------------------------
2072 | Function : tm_set_stop_all_ctrl_blk
2073 +------------------------------------------------------------------------------
2074 | Description :
2075 |
2076 | Parameters :
2077 |
2078 +------------------------------------------------------------------------------
2079 */
2080 GLOBAL void tm_set_stop_all_ctrl_blk ( void )
2081 {
2082 T_BLK_INDEX start_index = 0;
2083
2084 TRACE_FUNCTION( "tm_set_stop_all_ctrl_blk" );
2085
2086 while
2087 (
2088 ( start_index = tm_set_stop_ctrl_blk( FALSE,
2089 CGRLC_BLK_OWNER_NONE,
2090 start_index ) ) NEQ MAX_CTRL_BLK_NUM
2091 ){};
2092 } /* tm_set_stop_all_ctrl_blk() */
2093
2094 /*
2095 +------------------------------------------------------------------------------
2096 | Function : tm_get_gmm_prim_queue
2097 +------------------------------------------------------------------------------
2098 | Description : The function tm_get_gmm_prim_queue () ....
2099 |
2100 | Parameters : void
2101 |
2102 +------------------------------------------------------------------------------
2103 */
2104 GLOBAL void tm_get_gmm_prim_queue ( void )
2105 {
2106 UBYTE i;
2107 TRACE_FUNCTION( "tm_get_gmm_prim_queue " );
2108
2109
2110
2111 /* init gmm prim queue*/
2112 TRACE_EVENT_P4("GET GMM QUEUE: BEFORE ps=%d, pf=%d,sps=%d,spf=%d",
2113 grlc_data->prim_start_tbf,
2114 grlc_data->prim_start_free,
2115 grlc_data->save_prim_start_tbf,
2116 grlc_data->save_prim_start_free);
2117
2118 /*
2119 * Delte all GMM primitives in current llc queue, which are on the top.
2120 */
2121 while((grlc_data->prim_start_tbf >= PRIM_QUEUE_SIZE) AND
2122 (grlc_data->prim_start_tbf < PRIM_QUEUE_SIZE_TOTAL))
2123 {
2124 grlc_delete_prim();
2125 }
2126
2127 grlc_data->gmm_procedure_is_running = TRUE;
2128
2129 if(grlc_data->prim_start_free EQ 0xFF)
2130 {
2131 TRACE_ERROR("PRIM_QUEUE FULL: RAU MAY BE SENT, NEXT DATA PRIM WILL BE DELETED ");
2132 }
2133
2134 for (i=PRIM_QUEUE_SIZE; i<(PRIM_QUEUE_SIZE_TOTAL);i++)
2135 {
2136 grlc_data->prim_queue[i].next = i+1;
2137
2138 grlc_data->prim_queue[i].prim_ptr = NULL;
2139 grlc_data->prim_queue[i].prim_type = CGRLC_LLC_PRIM_TYPE_NULL;
2140 grlc_data->prim_queue[i].cv_status = FALSE;
2141 grlc_data->prim_queue[i].rlc_status = FALSE;
2142 grlc_data->prim_queue[i].re_allocation = FALSE;
2143 grlc_data->prim_queue[i].start_new_tbf = FALSE;
2144 grlc_data->prim_queue[i].last_bsn = 0xff;
2145 }
2146 grlc_data->prim_queue[PRIM_QUEUE_SIZE_TOTAL-1].next = 0xff;
2147
2148 grlc_data->save_prim_start_tbf = grlc_data->prim_start_tbf;
2149 grlc_data->save_prim_start_free = grlc_data->prim_start_free;
2150
2151 grlc_data->prim_start_tbf = 0xFF;
2152 grlc_data->prim_start_free = PRIM_QUEUE_SIZE;
2153 grlc_data->prim_user_data = 0;
2154 grlc_data->tm.send_grlc_ready_ind = SEND_A_GRLC_READY_IND;
2155
2156 TRACE_EVENT_P4("GET GMM QUEUE: AFTER ps=%d, pf=%d,sps=%d,spf=%d",
2157 grlc_data->prim_start_tbf,
2158 grlc_data->prim_start_free,
2159 grlc_data->save_prim_start_tbf,
2160 grlc_data->save_prim_start_free);
2161
2162
2163 } /* tm_get_gmm_prim_queue */
2164
2165 /*
2166 +------------------------------------------------------------------------------
2167 | Function : tm_get_llc_prim_queue
2168 +------------------------------------------------------------------------------
2169 | Description : The function tm_get_llc_prim_queue () ....
2170 |
2171 | Parameters : void
2172 |
2173 +------------------------------------------------------------------------------
2174 */
2175 GLOBAL void tm_get_llc_prim_queue ( void )
2176 {
2177 UBYTE i;
2178
2179 TRACE_FUNCTION( "tm_get_llc_prim_queue " );
2180
2181
2182 TRACE_EVENT_P4("GET LLC QUEUE: BEFORE ps=%d, pf=%d,sps=%d,spf=%d",
2183 grlc_data->prim_start_tbf,
2184 grlc_data->prim_start_free,
2185 grlc_data->save_prim_start_tbf,
2186 grlc_data->save_prim_start_free);
2187
2188
2189 if(grlc_data->prim_start_tbf < PRIM_QUEUE_SIZE_TOTAL)
2190 {
2191 /*finish gmm data and than resume with llc data*/
2192 i = grlc_data->prim_start_tbf;
2193 while(grlc_data->prim_queue[i].next NEQ 0xFF)
2194 {
2195 i = grlc_data->prim_queue[i].next;
2196 }
2197 grlc_data->prim_queue[i].next = grlc_data->save_prim_start_tbf;
2198 grlc_data->prim_queue[i].start_new_tbf = TRUE;
2199 }
2200 else
2201 {
2202 grlc_data->prim_start_tbf = grlc_data->save_prim_start_tbf;
2203 }
2204 grlc_data->prim_start_free = grlc_data->save_prim_start_free;
2205 grlc_data->gmm_procedure_is_running = FALSE;
2206 grlc_data->prim_user_data = 0;
2207 i = grlc_data->prim_start_tbf;
2208 while(i NEQ 0xFF)
2209 {
2210 grlc_data->prim_user_data += BYTELEN(grlc_data->prim_queue[i].prim_ptr->sdu.l_buf);
2211 i = grlc_data->prim_queue[i].next;
2212 }
2213
2214
2215 TRACE_EVENT_P4("GET LLC QUEUE: AFTER ps=%d, pf=%d,sps=%d,spf=%d",
2216 grlc_data->prim_start_tbf,
2217 grlc_data->prim_start_free,
2218 grlc_data->save_prim_start_tbf,
2219 grlc_data->save_prim_start_free);
2220
2221
2222
2223
2224 } /* tm_get_llc_prim_queue */
2225
2226 /*
2227 +------------------------------------------------------------------------------
2228 | Function : tm_ul_tbf_ind
2229 +------------------------------------------------------------------------------
2230 | Description : The function tm_ul_tbf_ind () ....
2231 |
2232 | Parameters : void
2233 |
2234 +------------------------------------------------------------------------------
2235 */
2236 GLOBAL void tm_ul_tbf_ind ( void )
2237 {
2238 TRACE_FUNCTION( "tm_ul_tbf_ind " );
2239
2240
2241
2242 switch(grlc_data->tbf_type)
2243 {
2244 case TBF_TYPE_NULL:
2245 if( grlc_data->prim_start_tbf < PRIM_QUEUE_SIZE_TOTAL )
2246 {
2247 PALLOC(cgrlc_ul_tbf_ind,CGRLC_UL_TBF_IND); /*T_CGRLC_UL_TBF_IND*/
2248
2249 tm_start_access();
2250
2251 cgrlc_ul_tbf_ind->access_type = grlc_data->uplink_tbf.access_type;
2252 cgrlc_ul_tbf_ind->ra_prio = grlc_data->uplink_tbf.prio;
2253 cgrlc_ul_tbf_ind->nr_blocks = grlc_data->uplink_tbf.nr_blocks;
2254 cgrlc_ul_tbf_ind->llc_prim_type = grlc_data->prim_queue[grlc_data->prim_start_tbf].prim_type;
2255 cgrlc_ul_tbf_ind->rlc_oct_cnt = grlc_data->prim_queue[grlc_data->prim_start_tbf].prim_ptr->sdu.l_buf/8 +1;
2256 cgrlc_ul_tbf_ind->peak = grlc_data->prim_queue[grlc_data->prim_start_tbf].prim_ptr->grlc_qos.peak;
2257 #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH
2258 cgrlc_ul_tbf_ind->tbf_est_pacch = FALSE;
2259 #endif
2260
2261 SET_STATE( TM, TM_PAM );
2262 PSEND(hCommGRR,cgrlc_ul_tbf_ind);
2263 }
2264 else
2265 {
2266 /*
2267 * inform higher layers that no tbf is requested
2268 */
2269 PALLOC(cgrlc_ul_tbf_ind,CGRLC_UL_TBF_IND); /*T_CGRLC_UL_TBF_IND*/
2270 cgrlc_ul_tbf_ind->access_type = CGRLC_AT_NULL;
2271 cgrlc_ul_tbf_ind->ra_prio = 0xEE;
2272 cgrlc_ul_tbf_ind->nr_blocks = 0xEE;
2273 cgrlc_ul_tbf_ind->llc_prim_type = 0xEE;
2274 cgrlc_ul_tbf_ind->peak = 0xEE;
2275 #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH
2276 cgrlc_ul_tbf_ind->tbf_est_pacch = FALSE;
2277 #endif
2278
2279
2280 PSEND(hCommGRR,cgrlc_ul_tbf_ind);
2281 /*
2282 * delete control message queue
2283 */
2284 tm_set_stop_all_ctrl_blk();
2285 }
2286 tm_handle_grlc_ready_ind( );
2287 break;
2288 case TBF_TYPE_DL:
2289 if( (grlc_data->prim_start_tbf < PRIM_QUEUE_SIZE_TOTAL) AND (!grlc_data->tm.n_res_req))
2290 {
2291 tm_start_access();
2292 tm_build_chan_req_des(&grlc_data->chan_req_des,
2293 &grlc_data->prim_queue[grlc_data->prim_start_tbf]);
2294 sig_tm_rd_ul_req();
2295 grlc_data->tm.n_res_req++;
2296 }
2297 break;
2298 case TBF_TYPE_CONC:
2299 case TBF_TYPE_UL:
2300 break;
2301 default:
2302 TRACE_ERROR("unknown tbf type during uplink access");
2303 break;
2304 }
2305 } /* tm_ul_tbf_ind */
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318 /*
2319 +------------------------------------------------------------------------------
2320 | Function : tm_tfi_handling
2321 +------------------------------------------------------------------------------
2322 | Description : The function tm_tfi_handling () handles modified tfi´s in
2323 | case of starting time
2324 |
2325 | Parameters : start_fn_present: indicates if a starting time is present
2326 | tbf_type : type of the current tbf
2327 | ul_tfi : new assignend uplink tfi
2328 | dl_tfi : new assignend downlink tfi
2329 |
2330 +------------------------------------------------------------------------------
2331 */
2332 GLOBAL void tm_tfi_handling (ULONG tbf_start,UBYTE tbf_type, UBYTE ul_tfi, UBYTE dl_tfi)
2333 {
2334
2335 TRACE_FUNCTION( "tm_tfi_handling " );
2336
2337
2338 /*TRACE_EVENT_P6("TFI CHANGE: =tbf_type = %d\n fn= %ld \n new_Utfi=%d old_Utfi=%d \n new_Dtfi=%d old_Dtfi=%d"
2339 ,tbf_type
2340 ,tbf_start
2341 ,ul_tfi
2342 ,grlc_data->ul_tfi
2343 ,dl_tfi
2344 ,grlc_data->dl_tfi);
2345
2346 */
2347 switch( tbf_type )
2348 {
2349 case CGRLC_TBF_MODE_UL:
2350 if((tbf_start NEQ CGRLC_STARTING_TIME_NOT_PRESENT) AND (ul_tfi NEQ grlc_data->ul_tfi)) /*lint !e650*/
2351 {
2352 if(grlc_data->tfi_change EQ TFI_CHANGE_NULL)
2353 grlc_data->tfi_change = TFI_CHANGE_UL;
2354 else if(grlc_data->tfi_change EQ TFI_CHANGE_DL)
2355 grlc_data->tfi_change = TFI_CHANGE_ALL;
2356 grlc_data->start_fn_ul_tfi = ul_tfi;
2357 grlc_data->ul_tbf_start_time = tbf_start;
2358 TRACE_EVENT_P3("GRLC UL TFI CHANGE AFTER ST. TIME = %ld new_tfi=%d old_tfi=%d"
2359 ,tbf_start
2360 ,ul_tfi
2361 ,grlc_data->ul_tfi);
2362 }
2363 else
2364 {
2365 if(grlc_data->tfi_change EQ TFI_CHANGE_UL)
2366 grlc_data->tfi_change = TFI_CHANGE_NULL;
2367 else if(grlc_data->tfi_change EQ TFI_CHANGE_ALL)
2368 grlc_data->tfi_change = TFI_CHANGE_DL;
2369 grlc_data->ul_tfi = ul_tfi;
2370 grlc_data->start_fn_ul_tfi = 0xFF;
2371 grlc_data->ul_tbf_start_time = CGRLC_STARTING_TIME_NOT_PRESENT;
2372 }
2373 #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH
2374 sig_tm_gff_ul_activate(GFF_ACTIVE);
2375 #else
2376 sig_tm_gff_ul_activate();
2377 #endif
2378 break;
2379 case CGRLC_TBF_MODE_DL:
2380 if((tbf_start NEQ CGRLC_STARTING_TIME_NOT_PRESENT) AND (dl_tfi NEQ grlc_data->dl_tfi)) /*lint !e650*/
2381 {
2382 if(grlc_data->tfi_change EQ TFI_CHANGE_NULL)
2383 grlc_data->tfi_change = TFI_CHANGE_DL;
2384 else if(grlc_data->tfi_change EQ TFI_CHANGE_UL)
2385 grlc_data->tfi_change = TFI_CHANGE_ALL;
2386 grlc_data->start_fn_dl_tfi = dl_tfi;
2387 grlc_data->dl_tbf_start_time = tbf_start;
2388 TRACE_EVENT_P3("GRLC DL TFI CHANGE AFTER ST. TIME =%ld new_tfi=%d old_tfi=%d"
2389 ,tbf_start
2390 ,dl_tfi
2391 ,grlc_data->dl_tfi);
2392 }
2393 else
2394 {
2395 if(grlc_data->tfi_change EQ TFI_CHANGE_DL)
2396 grlc_data->tfi_change = TFI_CHANGE_NULL;
2397 else if(grlc_data->tfi_change EQ TFI_CHANGE_ALL)
2398 grlc_data->tfi_change = TFI_CHANGE_UL;
2399 grlc_data->dl_tfi = dl_tfi;
2400 grlc_data->start_fn_dl_tfi = 0xFF;
2401 grlc_data->dl_tbf_start_time = CGRLC_STARTING_TIME_NOT_PRESENT;
2402 }
2403 sig_tm_gff_dl_activate();
2404 break;
2405 #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH
2406 case CGRLC_TBF_MODE_2PA:
2407 sig_tm_gff_ul_activate(GFF_TWO_PHASE);
2408 break;
2409 #endif
2410
2411 }
2412
2413
2414 /*TRACE_EVENT_P1("TFI_CHANGE = %d",grlc_data->tfi_change );*/
2415
2416 } /* tm_tfi_handling () */
2417
2418
2419
2420 /*
2421 +------------------------------------------------------------------------------
2422 | Function : tm_cgrlc_status_ind
2423 +------------------------------------------------------------------------------
2424 | Description : Handles the primitive CGRLC_STATUS_IND
2425 |
2426 | Parameters : cause - status cause, gmm is informed
2427 |
2428 +------------------------------------------------------------------------------
2429 */
2430 GLOBAL void tm_cgrlc_status_ind ( UBYTE cause )
2431 {
2432 PALLOC(cgrlc_status_ind,CGRLC_STATUS_IND);
2433
2434 TRACE_FUNCTION( "tm_cgrlc_status_ind" );
2435
2436 cgrlc_status_ind->failure = cause;
2437 PSEND(hCommGMM,cgrlc_status_ind);
2438
2439 TRACE_EVENT_P1("error cause = %ld",cause);
2440
2441
2442 }/* tm_cgrlc_status_ind*/
2443
2444 /*
2445 +------------------------------------------------------------------------------
2446 | Function : tm_handle_polling_bit
2447 +------------------------------------------------------------------------------
2448 | Description : Handles the the polling in the immediate assignment (uplink or
2449 | downlink)
2450 |
2451 | Parameters : st_fn - starting time
2452 | tn - timeslot
2453 |
2454 +------------------------------------------------------------------------------
2455 */
2456 GLOBAL void tm_handle_polling_bit ( ULONG st_fn, UBYTE tn )
2457 {
2458
2459 TRACE_FUNCTION( "tm_handle_polling_bit" );
2460
2461
2462
2463 grlc_data->next_poll_fn = st_fn;
2464 grlc_data->ul_poll_pos_index = 0;
2465 if(grlc_data->burst_type EQ 0)
2466 {
2467 grlc_send_access_burst( tn );
2468 }
2469 else
2470 {
2471 grlc_send_normal_burst(grlc_set_packet_ctrl_ack(), NULL, tn);
2472 }
2473
2474
2475
2476 }/* tm_handle_polling_bit */
2477
2478
2479
2480 /*
2481 +------------------------------------------------------------------------------
2482 | Function : tm_store_fa_bitmap
2483 +------------------------------------------------------------------------------
2484 | Description : This function stores the allocation bitmap in
2485 | case of fixed allocation
2486 |
2487 | Parameters : ptr2_fix_alloc - ptr to the fixed allocation struct
2488 |
2489 +------------------------------------------------------------------------------
2490 */
2491 GLOBAL void tm_store_fa_bitmap (T_CGRLC_fix_alloc_struct * ptr2_fix_alloc)
2492 {
2493 UBYTE i,j;
2494 USHORT ul_res_sum = 0;
2495 T_FA_ALLOC * ptr_fa_ctrl;
2496
2497 TRACE_FUNCTION( "tm_store_fa_bitmap" );
2498
2499
2500 /*
2501 * calculate uplink resources allocation
2502 */
2503
2504 for(i=0;i<ptr2_fix_alloc->bitmap_len;i++)
2505 {
2506 if(ptr2_fix_alloc->bitmap_array[i])
2507 {
2508 UBYTE mask = 0x80;
2509
2510 for(j=0; j<=7; j++)
2511 {
2512 if(ptr2_fix_alloc->bitmap_array[i] & mask)
2513 ul_res_sum++;
2514 mask>>=1;
2515 }
2516 }
2517 }
2518
2519
2520 /*
2521 * set fa_ctrl
2522 */
2523 if(grlc_data->uplink_tbf.fa_manag.fa_type EQ FA_NO_CURRENT)
2524 {
2525 grlc_data->uplink_tbf.fa_manag.fa_type = FA_NO_NEXT;
2526 ptr_fa_ctrl = &grlc_data->uplink_tbf.fa_manag.current_alloc;
2527 ptr_fa_ctrl->alloc_start_fn = grlc_data->ul_tbf_start_time;
2528 ptr_fa_ctrl->alloc_end_fn = ptr2_fix_alloc->end_fn;
2529 }
2530 else
2531 {
2532 grlc_data->uplink_tbf.fa_manag.fa_type = FA_BITMAP;
2533 ptr_fa_ctrl = &grlc_data->uplink_tbf.fa_manag.next_alloc;
2534 ptr_fa_ctrl->alloc_start_fn = grlc_data->ul_tbf_start_time;
2535
2536 /*
2537 * check conflict of end of current alloc and start of next alloc
2538 */
2539 if( grlc_check_dist(grlc_data->uplink_tbf.fa_manag.current_alloc.alloc_end_fn,
2540 grlc_data->uplink_tbf.fa_manag.next_alloc.alloc_start_fn,10000))
2541 {
2542 ULONG delta_fn;
2543 UBYTE idle_frames;
2544 UBYTE iden_radio_blocks;
2545 UBYTE ts_delet;
2546
2547 delta_fn = grlc_data->uplink_tbf.fa_manag.current_alloc.alloc_end_fn -
2548 grlc_data->uplink_tbf.fa_manag.next_alloc.alloc_start_fn;
2549 idle_frames = (UBYTE)((delta_fn / 52) *4 + delta_fn % 4);
2550 iden_radio_blocks = (UBYTE)((delta_fn - idle_frames) / 4 + 1);
2551
2552 /*
2553 * remove shared allocation from current allocation
2554 */
2555 ts_delet = 0;
2556 for(i=0;i<iden_radio_blocks;i++)
2557 {
2558 UBYTE pos;
2559 pos = grlc_data->uplink_tbf.fa_manag.current_alloc.alloc.bitmap_len - i;
2560
2561 /*
2562 * calculate number of timeslots for current frame and delete them from resources
2563 */
2564 if(grlc_data->uplink_tbf.fa_manag.current_alloc.alloc.bitmap_array[pos])
2565 {
2566 UBYTE mask = 0x80;
2567
2568 for(j=0; j<=7; j++)
2569 {
2570 if(ptr2_fix_alloc->bitmap_array[i] & mask)
2571 ts_delet++;
2572 mask>>=1;
2573 }
2574 }
2575 grlc_data->uplink_tbf.fa_manag.current_alloc.alloc.bitmap_array[pos] = 0;
2576 }
2577 grlc_data->uplink_tbf.fa_manag.current_alloc.ul_res_sum -= ts_delet;
2578 grlc_data->uplink_tbf.fa_manag.ul_res_sum -= ts_delet;
2579 grlc_data->uplink_tbf.fa_manag.current_alloc.alloc.bitmap_len -= iden_radio_blocks;
2580 grlc_data->uplink_tbf.fa_manag.current_alloc.alloc_end_fn =
2581 grlc_data->uplink_tbf.fa_manag.current_alloc.alloc_end_fn - delta_fn;
2582 }
2583 }
2584 grlc_data->uplink_tbf.fa_manag.ul_res_sum += ul_res_sum;
2585 ptr_fa_ctrl->ul_res_sum = ul_res_sum;
2586 /*
2587 * store end of fixed allocation
2588 */
2589 ptr_fa_ctrl->alloc_end_fn = ptr2_fix_alloc->end_fn;
2590
2591
2592 tm_handle_final_alloc (ptr2_fix_alloc->final_alloc);
2593
2594 } /* tm_store_fa_bitmap() */
2595
2596
2597 /*
2598 +------------------------------------------------------------------------------
2599 | Function : tm_handle_final_alloc
2600 +------------------------------------------------------------------------------
2601 | Description : This function handles the final allocation bit.
2602 |
2603 | Parameters : -
2604 |
2605 +------------------------------------------------------------------------------
2606 */
2607 GLOBAL void tm_handle_final_alloc (UBYTE final_allocation)
2608 {
2609 UBYTE next;
2610 T_RLC_VALUES rlc_val;
2611 USHORT rlc_data_size=0;
2612
2613 TRACE_FUNCTION( "tm_handle_final_alloc" );
2614
2615 switch(grlc_data->uplink_tbf.cs_type)
2616 {
2617 case CS_1:
2618 rlc_data_size = 20;
2619 break;
2620 case CS_2:
2621 rlc_data_size = 30;
2622 break;
2623 case CS_3:
2624 rlc_data_size = 36;
2625 break;
2626 case CS_4:
2627 rlc_data_size = 50;
2628 break;
2629 default:
2630 break;
2631 }
2632 if(grlc_data->prim_start_tbf < PRIM_QUEUE_SIZE_TOTAL AND
2633 grlc_data->prim_queue[grlc_data->prim_start_tbf].rlc_status EQ FALSE )
2634 {
2635 next = grlc_data->prim_queue[grlc_data->prim_start_tbf].next;
2636 }
2637 else
2638 {
2639 next = grlc_data->prim_start_tbf;
2640 TRACE_EVENT_P3("PST=%d PSF=%d PDU=%d: tm_handle_final_alloc"
2641 ,grlc_data->prim_start_tbf
2642 ,grlc_data->prim_start_free
2643 ,grlc_data->grlc_data_req_cnt);
2644
2645 }
2646 grlc_get_sdu_len_and_used_ts( &rlc_val);
2647 grlc_data->uplink_tbf.fa_manag.tbf_oct_cnt = rlc_val.sdu_len;
2648 grlc_data->uplink_tbf.fa_manag.ul_res_used = rlc_val.cnt_ts;
2649 grlc_data->uplink_tbf.fa_manag.ul_res_remain =
2650 grlc_data->uplink_tbf.fa_manag.ul_res_sum - grlc_data->uplink_tbf.fa_manag.ul_res_used;
2651 grlc_data->uplink_tbf.fa_manag.tbf_oct_cap_remain = grlc_data->uplink_tbf.fa_manag.ul_res_remain * rlc_data_size;
2652
2653 if(final_allocation)
2654 {
2655 /*
2656 * last allocation of the tbf, it must end at the end of tbf.
2657 * check if more data is in prim queue than available uplink resources.
2658 * NO: nothing to do
2659 * YES: reorganize prim queue(set start_new_tbf) and inform RU
2660 */
2661
2662
2663 while((grlc_data->prim_queue[next].start_new_tbf EQ 0) AND
2664 (next NEQ 0xFF) )
2665 {
2666 if(grlc_data->uplink_tbf.fa_manag.tbf_oct_cap_remain <
2667 (grlc_data->uplink_tbf.fa_manag.tbf_oct_cnt + grlc_data->prim_queue[next].prim_ptr->sdu.l_buf/8 + 1))
2668 {
2669 /*
2670 * find the end of the tbf.
2671 */
2672 grlc_data->prim_queue[next].start_new_tbf = 1;
2673 sig_tm_ru_queue_status();
2674 return;
2675 }
2676 grlc_data->uplink_tbf.fa_manag.tbf_oct_cnt += grlc_data->prim_queue[next].prim_ptr->sdu.l_buf/8;
2677 grlc_data->uplink_tbf.fa_manag.tbf_oct_cnt++; /* for pdu boundaries */
2678 next = grlc_data->prim_queue[next].next;
2679 }
2680 }
2681 else
2682 {
2683 /*
2684 * not the last allocation
2685 */
2686 while((grlc_data->prim_queue[next].start_new_tbf EQ 0) AND
2687 (next NEQ 0xFF) )
2688 {
2689 grlc_data->uplink_tbf.fa_manag.tbf_oct_cnt += grlc_data->prim_queue[next].prim_ptr->sdu.l_buf/8;
2690 grlc_data->uplink_tbf.fa_manag.tbf_oct_cnt++; /* for pdu boundaries */
2691 next = grlc_data->prim_queue[next].next;
2692 }
2693 }
2694
2695
2696 } /* tm_handle_final_alloc() */
2697
2698
2699 /*
2700 +------------------------------------------------------------------------------
2701 | Function : tm_set_fa_bitmap
2702 +------------------------------------------------------------------------------
2703 | Description : sets fixed allocation bitmap for requested allocation after
2704 | receiving a repeat allocation with ts_override
2705 |
2706 | Parameters : void
2707 |
2708 +------------------------------------------------------------------------------
2709 */
2710 GLOBAL USHORT tm_set_fa_bitmap( UBYTE ts_mask, T_FA_ALLOC* ptr_alloc)
2711 {
2712 UBYTE i,j;
2713 USHORT tx_slots;
2714 TRACE_FUNCTION( "tm_set_fa_bitmap" );
2715
2716 if (ts_mask)
2717 {
2718 /*
2719 * add new time slots to current allocation
2720 */
2721 tx_slots = 0;
2722 for(i=0;i<grlc_data->uplink_tbf.fa_manag.current_alloc.alloc.bitmap_len;i++)
2723 {
2724 ptr_alloc->alloc.bitmap_array[i] = grlc_data->uplink_tbf.fa_manag.current_alloc.alloc.bitmap_array[i] | ts_mask;
2725
2726 if(ptr_alloc->alloc.bitmap_array[i])
2727 {
2728 UBYTE mask = 0x80;
2729
2730 for(j=0; j<=7; j++)
2731 {
2732 if(ptr_alloc->alloc.bitmap_array[i] & mask)
2733 tx_slots++;
2734 mask>>=1;
2735 }
2736 }
2737
2738
2739 }
2740 }
2741 else
2742 {
2743 /*
2744 * no new timeslot allocated
2745 */
2746 tx_slots = grlc_data->uplink_tbf.fa_manag.current_alloc.ul_res_sum;
2747 }
2748 return (tx_slots);
2749
2750 } /* tm_set_fa_bitmap() */
2751
2752 /*
2753 +------------------------------------------------------------------------------
2754 | Function : tm_handle_test_mode_cnf
2755 +------------------------------------------------------------------------------
2756 | Description :
2757 |
2758 | Parameters :
2759 |
2760 +------------------------------------------------------------------------------
2761 */
2762 GLOBAL void tm_handle_test_mode_cnf ( BOOL v_test_mode_cnf )
2763 {
2764 TRACE_FUNCTION( "tm_handle_test_mode_cnf" );
2765
2766 if( v_test_mode_cnf EQ TRUE )
2767 {
2768 PALLOC( cgrlc_test_mode_cnf, CGRLC_TEST_MODE_CNF );
2769
2770 grlc_data->testmode.mode = CGRLC_NO_TEST_MODE;
2771
2772 PSEND( hCommGMM, cgrlc_test_mode_cnf );
2773
2774 tm_delete_prim_queue();
2775 /*inform grr that testmode is finished*/
2776 {
2777 PALLOC(cgrlc_test_mode_ind,CGRLC_TEST_MODE_IND); /*T_CGRLC_TEST_MODE_IND*/
2778 cgrlc_test_mode_ind->test_mode_flag = CGRLC_NO_TEST_MODE;
2779 PSEND(hCommGRR,cgrlc_test_mode_ind);
2780 }
2781
2782 }
2783 } /* tm_handle_test_mode_cnf() */
2784
2785 /*
2786 +------------------------------------------------------------------------------
2787 | Function : tm_prcs_pwr_ctrl
2788 +------------------------------------------------------------------------------
2789 | Description :
2790 |
2791 | Parameters :
2792 |
2793 +------------------------------------------------------------------------------
2794 */
2795 GLOBAL void tm_prcs_pwr_ctrl ( T_CGRLC_pwr_ctrl *pwr_ctrl )
2796 {
2797 TRACE_FUNCTION( "tm_prcs_pwr_ctrl" );
2798
2799 if( pwr_ctrl->v_pwr_ctrl_param )
2800 {
2801 tpc_set_pwr_ctrl_param( &pwr_ctrl->pwr_ctrl_param );
2802 }
2803
2804 if( pwr_ctrl->v_glbl_pwr_ctrl_param )
2805 {
2806 tpc_set_glbl_pwr_ctrl_param( &pwr_ctrl->glbl_pwr_ctrl_param );
2807 }
2808
2809 if( pwr_ctrl->v_freq_param )
2810 {
2811 grlc_data->tm.freq_param = pwr_ctrl->freq_param;
2812 }
2813
2814 if( pwr_ctrl->v_c_value )
2815 {
2816 meas_grlc_c_set_c_value( &pwr_ctrl->c_value );
2817 }
2818
2819 sig_tm_tpc_update_pch( );
2820
2821 {
2822 PALLOC( pwr_ctrl_cnf, CGRLC_PWR_CTRL_CNF );
2823 PSEND( hCommGRR, pwr_ctrl_cnf );
2824 }
2825 } /* tm_prcs_pwr_ctrl() */
2826
2827
2828 #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH
2829 GLOBAL void tm_send_msg_directly_to_l1_queue (UBYTE * unencoded_msg)
2830 {
2831
2832 TRACE_FUNCTION( "tm_send_msg_directly_to_l1_queue" );
2833
2834 /* Call function that formats ARAC message */
2835
2836 memset(&grlc_data->ru.ul_data[0],
2837 0,
2838 sizeof(T_ul_data));
2839
2840 grlc_data->ru.ul_data[0].block_status = 2;
2841 grlc_encode_ul_ctrl_block(( UBYTE* ) grlc_data->ru.ul_data[0].ul_block,
2842 ( UBYTE* )unencoded_msg );
2843
2844 #ifdef _SIMULATION_
2845 {
2846 PALLOC(mac_data_req,MAC_DATA_REQ);
2847 memset(&(mac_data_req->ul_data),
2848 0,
2849 sizeof(T_ul_data));
2850 memcpy(&(mac_data_req->ul_data),
2851 &(grlc_data->ru.ul_data[0]),
2852 sizeof(T_ul_data));
2853 PSEND(hCommL1,mac_data_req);
2854 }
2855 #else
2856 /* No need to copy again */
2857 #endif /* ! _SIMULATION_ */
2858
2859 grlc_data->ru.ul_data[1].block_status = 0;
2860 return;
2861
2862 }
2863
2864
2865 GLOBAL void tm_send_prr_2p_ptm ( void )
2866 {
2867 T_U_GRLC_RESOURCE_REQ resource_req;
2868
2869 TRACE_FUNCTION( "tm_send_prr_2p_ptm" );
2870
2871 tm_build_res_req( &resource_req, R_BUILD_2PHASE_ACCESS);
2872
2873 tm_send_msg_directly_to_l1_queue((UBYTE *)&resource_req);
2874
2875 return;
2876
2877 }
2878 #endif