comparison src/g23m-gprs/grlc/grlc_rds.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 : 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 signal handler functions for service
18 | RD of entity GRLC.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef GRLC_RDS_C
23 #define GRLC_RDS_C
24 #endif
25
26 #define ENTITY_GRLC
27
28 /*==== INCLUDES =============================================================*/
29 #include <string.h>
30
31 #include "typedefs.h" /* to get Condat data types */
32
33 #include "vsi.h" /* to get a lot of macros */
34 #include "macdef.h"
35 #include "gprs.h"
36 #include "gsm.h" /* to get a lot of macros */
37 #include "ccdapi.h" /* to get CCD API */
38 #include "cnf_grlc.h" /* to get cnf-definitions */
39 #include "mon_grlc.h" /* to get mon-definitions */
40 #include "prim.h" /* to get the definitions of used SAP and directions */
41 #include "message.h"
42 #include "grlc.h" /* to get the global entity definitions */
43 #include "grlc_rdf.h"
44 #include "grlc_tms.h"
45 #include "grlc_f.h"
46 #include "grlc_meass.h"
47
48 /*==== CONST ================================================================*/
49 const T_TIME T3192_Values[8] = {500, 1000, 1500, 1, 80, 120, 160, 200};
50
51 /*==== LOCAL VARS ===========================================================*/
52
53 /*==== PRIVATE FUNCTIONS ====================================================*/
54
55 /*==== PUBLIC FUNCTIONS =====================================================*/
56
57
58
59 /*
60 +------------------------------------------------------------------------------
61 | Function : sig_tm_rd_assign
62 +------------------------------------------------------------------------------
63 | Description : Handles the internal signal SIG_TM_RD_ASSIGN
64 |
65 | Parameters : dummy - description of parameter dummy
66 |
67 +------------------------------------------------------------------------------
68 */
69 GLOBAL void sig_tm_rd_assign ( void )
70 {
71 TRACE_ISIG( "sig_tm_rd_assign" );
72
73 switch( GET_STATE( RD ) )
74 {
75 case RD_WAIT_FOR_STARTING_TIME_ACK:
76 case RD_WAIT_FOR_STARTING_TIME_UACK:
77 TRACE_EVENT_P3("DL reassignment during starting time :%ld: dl_tfi=%d, st_dl_tfi=%d"
78 ,grlc_data->dl_tbf_start_time
79 ,grlc_data->dl_tfi
80 ,grlc_data->start_fn_dl_tfi);
81
82
83 /*lint -fallthrough*/
84
85 case RD_NULL:
86 rd_tbf_init();
87 if(grlc_data->rd.rlc_mode EQ CGRLC_RLC_MODE_ACK)
88 {
89 SET_STATE(RD,RD_WAIT_FOR_STARTING_TIME_ACK);
90 }
91 else
92 {
93 SET_STATE(RD,RD_WAIT_FOR_STARTING_TIME_UACK);
94 }
95 grlc_data->dl_index = 1;
96 grlc_data->tbf_ctrl[grlc_data->dl_index].tbf_type = TBF_TYPE_DL;
97 grlc_data->tbf_ctrl[grlc_data->dl_index].tfi = grlc_data->dl_tfi;
98 grlc_data->tbf_ctrl[grlc_data->dl_index].pdu_cnt = 0;
99 grlc_data->tbf_ctrl[grlc_data->dl_index].rlc_oct_cnt = 0;
100 grlc_data->tbf_ctrl[grlc_data->dl_index].cnt_ts = 0;
101 grlc_data->tbf_ctrl[grlc_data->dl_index].ack_cnt = 0;
102 grlc_data->tbf_ctrl[grlc_data->dl_index].fbi = 0;
103 grlc_data->tbf_ctrl[grlc_data->dl_index].ret_bsn = 0;
104
105 grlc_data->rd.ack_ctrl.cnt_meas_rpt = ACK_CNT_MEAS_RPT_FIRST;
106 grlc_data->rd.ack_ctrl.cnt_other = ACK_CNT_NORMAL;
107 break;
108 case RD_ACK:
109 case RD_UACK:
110 vsi_t_stop(GRLC_handle,T3190);
111 vsi_t_start(GRLC_handle,T3190,T3190_VALUE);
112 grlc_data->rd.next_tbf_params = grlc_data->downlink_tbf;
113 grlc_data->rd.v_next_tbf_params = TRUE;
114 TRACE_EVENT_P3("dl tbf reassignment with tfi %d, nts=%d tbf_st_time=%ld"
115 ,grlc_data->dl_tfi
116 ,grlc_data->downlink_tbf.nts
117 ,grlc_data->dl_tbf_start_time);
118 break;
119 default:
120 TRACE_ERROR( "SIG_TM_RD_ASSIGN unexpected" );
121 {
122 TRACE_EVENT_P2("DL ASS: state=%d t3192=%d "
123 ,grlc_data->rd.state
124 ,grlc_data->downlink_tbf.t3192_val );
125 }
126 break;
127 }
128 } /* sig_tm_rd_assign() */
129
130
131
132 /*
133 +------------------------------------------------------------------------------
134 | Function : sig_tm_rd_abrel
135 +------------------------------------------------------------------------------
136 | Description : Handles the internal signal SIG_TM_RD_ABREL
137 |
138 | Parameters : dummy - description of parameter dummy
139 |
140 +------------------------------------------------------------------------------
141 */
142 GLOBAL void sig_tm_rd_abrel ( ULONG fn, BOOL poll)
143 {
144 TRACE_ISIG( "sig_tm_rd_abrel" );
145
146 switch( GET_STATE( RD ) )
147 {
148 case RD_ACK:
149 case RD_REL_ACK:
150 case RD_UACK:
151 case RD_REL_UACK:
152 case RD_NET_REL:
153 case RD_WAIT_FOR_STARTING_TIME_ACK:
154 case RD_WAIT_FOR_STARTING_TIME_UACK:
155 vsi_t_stop(GRLC_handle,T3190);
156 vsi_t_stop(GRLC_handle,T3192);
157
158 rd_free_desc_list_partions();
159 rd_free_database_partions();
160
161 grlc_data->tbf_ctrl[grlc_data->dl_index].vs_vr = grlc_data->rd.vr;
162 grlc_data->tbf_ctrl[grlc_data->dl_index].va_vq = grlc_data->rd.vq;
163 grlc_trace_tbf_par ( grlc_data->dl_index );
164
165 if(!poll)
166 {
167 /*
168 * abnormal release: abort TBF
169 */
170 SET_STATE(RD,RD_NULL);
171 }
172 else
173 {
174 SET_STATE(RD,RD_NET_REL);
175 grlc_data->rd.fn_p_tbf_rel = fn;
176 TRACE_EVENT_P2("p. tbf rel c_fn=%ld poll_fn=%d",fn,grlc_data->rd.fn_p_tbf_rel);
177 }
178 break;
179 default:
180 TRACE_ERROR( "SIG_TM_RD_ABREL unexpected" );
181 break;
182 }
183 } /* sig_tm_rd_abrel() */
184
185 /*
186 +------------------------------------------------------------------------------
187 | Function : sig_tm_rd_ul_req
188 +------------------------------------------------------------------------------
189 | Description : Handles the internal signal SIG_TM_RD_UL_REQ
190 |
191 | Parameters : dummy - description of parameter dummy
192 |
193 +------------------------------------------------------------------------------
194 */
195 GLOBAL void sig_tm_rd_ul_req ( void)
196 {
197 TRACE_ISIG( "sig_tm_rd_ul_req" );
198
199 switch( GET_STATE( RD ) )
200 {
201 case RD_ACK:
202 case RD_REL_ACK:
203 case RD_UACK:
204 case RD_REL_UACK:
205 case RD_WAIT_FOR_STARTING_TIME_ACK:
206 case RD_WAIT_FOR_STARTING_TIME_UACK:
207 grlc_data->rd.channel_req = TRUE;
208 break;
209 default:
210 TRACE_ERROR( "SIG_TM_RD_UL_REQ unexpected" );
211 break;
212 }
213 } /* sig_tm_rd_ul_req() */
214
215
216 /*
217 +------------------------------------------------------------------------------
218 | Function : sig_tm_rd_ul_req_stop
219 +------------------------------------------------------------------------------
220 | Description : Handles the internal signal SIG_TM_RD_UL_REQ_STOP: No packet
221 | channel description shall be sent in packet downlink ack/nack,
222 | because a valid packet uplink assignment is received
223 |
224 | Parameters : dummy - description of parameter dummy
225 |
226 +------------------------------------------------------------------------------
227 */
228 GLOBAL void sig_tm_rd_ul_req_stop ( void)
229 {
230 TRACE_ISIG( "sig_tm_rd_ul_req_stop" );
231 /*
232 * do it in every state
233 */
234 grlc_data->rd.channel_req = FALSE;
235
236 } /* sig_tm_rd_ul_req_stop() */
237
238 /*
239 +------------------------------------------------------------------------------
240 | Function : sig_tm_rd_nor_rel
241 +------------------------------------------------------------------------------
242 | Description : Handles the internal signal SIG_TM_RD_NOR_REL
243 |
244 | Parameters : dummy - description of parameter dummy
245 |
246 +------------------------------------------------------------------------------
247 */
248 GLOBAL void sig_tm_rd_nor_rel ( void)
249 {
250 TRACE_ISIG( "sig_tm_rd_nor_rel" );
251
252 switch( GET_STATE( RD ) )
253 {
254 case RD_NULL:
255 case RD_ACK:
256 case RD_REL_ACK:
257 case RD_UACK:
258 case RD_REL_UACK:
259 case RD_NET_REL:
260 case RD_WAIT_FOR_STARTING_TIME_ACK:
261 case RD_WAIT_FOR_STARTING_TIME_UACK:
262 SET_STATE(RD,RD_NULL);
263 vsi_t_stop(GRLC_handle,T3190);
264 vsi_t_stop(GRLC_handle,T3192);
265 grlc_data->tbf_ctrl[grlc_data->dl_index].vs_vr = grlc_data->rd.vr;
266 grlc_data->tbf_ctrl[grlc_data->dl_index].va_vq = grlc_data->rd.vq;
267 grlc_trace_tbf_par ( grlc_data->dl_index );
268 break;
269 default:
270 TRACE_ERROR( "SIG_TM_RD_NOR_REL unexpected" );
271 break;
272 }
273 } /* sig_tm_rd_nor_rel() */
274
275
276
277
278
279 /*
280 +------------------------------------------------------------------------------
281 | Function : sig_gff_rd_mac_ready_ind
282 +------------------------------------------------------------------------------
283 | Description : Handles the Signal sig_gff_rd_mac_ready_ind
284 |
285 | Parameters : *mac_dl_ready_ind - Ptr to primitive MAC_READY_IND
286 |
287 +------------------------------------------------------------------------------
288 */
289 GLOBAL void sig_gff_rd_mac_ready_ind ( T_MAC_READY_IND * mac_dl_ready_ind)
290 {
291 UBYTE *ptr_block=NULL;
292 ULONG delta_fn;
293
294 TRACE_ISIG( "sig_gff_rd_mac_ready_ind" );
295
296
297 grlc_data->tbf_ctrl[grlc_data->dl_index].end_fn = mac_dl_ready_ind->fn;
298
299 grlc_handle_poll_pos (mac_dl_ready_ind->fn);
300 delta_fn = rd_calc_delta_fn(mac_dl_ready_ind->fn);
301
302 switch( GET_STATE( RD ) )
303 {
304 case RD_WAIT_FOR_STARTING_TIME_ACK:
305 case RD_WAIT_FOR_STARTING_TIME_UACK:
306 if(!grlc_check_if_tbf_start_is_elapsed ( grlc_data->dl_tbf_start_time, mac_dl_ready_ind->fn))
307 {
308 TRACE_EVENT_P2("WAIT FOR DL STARTING TIME, UL IS RUNNING st=%ld fn=%ld",grlc_data->dl_tbf_start_time
309 ,mac_dl_ready_ind->fn);
310 grlc_send_rem_poll_pos (mac_dl_ready_ind->fn);
311 return;
312 }
313 if(grlc_data->rd.rlc_mode EQ CGRLC_RLC_MODE_ACK)
314 {
315 SET_STATE(RD,RD_ACK);
316 }
317 else
318 {
319 SET_STATE(RD,RD_UACK);
320 }
321 grlc_data->tbf_ctrl[grlc_data->dl_index].start_fn = mac_dl_ready_ind->fn;
322
323 TRACE_EVENT_P6("DL first call at fn = %ld (%ld) with tfi=%d, dl_mask=%x tbf_st_time=%ld ta=%d",
324 mac_dl_ready_ind->fn,
325 mac_dl_ready_ind->fn%42432,
326 grlc_data->dl_tfi,
327 grlc_data->dl_tn_mask,
328 grlc_data->dl_tbf_start_time,
329 grlc_data->ta_value);
330 rd_cgrlc_st_time_ind();
331 vsi_t_start(GRLC_handle,T3190,T3190_VALUE);
332
333 /*lint -fallthrough*/
334
335 case RD_ACK:
336 case RD_REL_ACK:
337 case RD_UACK:
338 case RD_REL_UACK:
339 if(grlc_data->rd.v_next_tbf_params AND
340 grlc_check_if_tbf_start_is_elapsed ( grlc_data->dl_tbf_start_time, mac_dl_ready_ind->fn))
341 {
342 grlc_data->rd.v_next_tbf_params = FALSE;
343 rd_cgrlc_st_time_ind();
344 vsi_t_start(GRLC_handle,T3190,T3190_VALUE);
345 }
346 if(grlc_data->rd.ch_req_in_ack_prog AND mac_dl_ready_ind->last_poll_resp)
347 {
348 grlc_data->rd.channel_req = TRUE;
349 }
350 else if(grlc_data->rd.ch_req_in_ack_prog)
351 {
352 sig_rd_tm_ul_req_cnf();
353 grlc_data->rd.ch_req_in_ack_prog = FALSE;
354 }
355
356
357 if(grlc_data->rd.release_tbf)
358 {
359 /*
360 * Packet downlink ack/nack with final ack bit set to 1 was programmed
361 */
362 grlc_data->rd.release_tbf = FALSE;
363 if(mac_dl_ready_ind->last_poll_resp EQ 0)
364 {
365 /*
366 * Transmission from L1 confirmed
367 */
368 grlc_data->rd.cnt_sent_f_ack++;
369 }
370
371 }
372
373
374 if( grlc_data->rd.f_ack_ind AND
375 (grlc_data->rd.fn_p_tbf_rel NEQ 0xFFFFFFFF) AND
376 grlc_check_if_tbf_start_is_elapsed ( grlc_data->rd.fn_p_tbf_rel, mac_dl_ready_ind->fn))
377 {
378 /*
379 * no addtional final downlink ack with fbi requested by the network
380 * T3192 can be started
381 */
382
383 vsi_t_stop(GRLC_handle,T3190);
384
385 if(grlc_data->rd.cnt_sent_f_ack)
386 {
387 /*
388 * it is only a retransmission of the final dl ack.
389 * Therefore t3192 is restarted, no offset is needed
390 */
391 vsi_t_start(GRLC_handle,T3192, T3192_Values[grlc_data->downlink_tbf.t3192_val]);
392 TRACE_EVENT_P3("T3192 started: rel_fn=%ld fn=%ld T3192=%d",grlc_data->rd.fn_p_tbf_rel,mac_dl_ready_ind->fn,grlc_data->downlink_tbf.t3192_val);
393 }
394 else
395 {
396 /*
397 * the first final dl ack is not retransmitted, therefore retransmission is required.
398 * start t3190 and wait for new poll position
399 */
400 vsi_t_start(GRLC_handle,T3190,T3190_VALUE);
401 TRACE_EVENT_P1("NO DL REL: ret needed T3190 is running %d",grlc_data->rd.cnt_sent_f_ack);
402 }
403 grlc_data->rd.fn_p_tbf_rel = 0xFFFFFFFF;
404 }
405
406
407 if( (delta_fn EQ 4)
408 OR
409 (delta_fn EQ 5))
410 {
411 UBYTE i=0;
412 UBYTE index;
413 while(grlc_data->next_poll_array[grlc_data->poll_start_tbf].cnt
414 AND
415 (i<8))
416 {
417 if(grlc_data->next_poll_array[grlc_data->poll_start_tbf].poll_type[i] EQ CGRLC_POLL_DATA)
418 {
419 /*
420 * poll positon in next frame present,
421 * counter for for poll postions in one frame
422 */
423 if( grlc_data->rd.channel_req OR /* uplink request */
424 grlc_data->rd.next_poll_block EQ NEXT_POLL_BLOCK_DL_DATA OR /* last poll block was not ack nack */
425 grlc_data->rd.f_ack_ind OR /* final ack indicator */
426 !tm_is_ctrl_blk_rdy
427 ( grlc_data->rd.ack_ctrl.cnt_meas_rpt,
428 grlc_data->rd.ack_ctrl.cnt_other ) ) /* no ctrl message */
429 {
430 if ( !((grlc_data->rd.rlc_mode EQ CGRLC_RLC_MODE_UACK) AND grlc_data->rd.f_ack_ind) )
431 {
432 /*
433 * sent downlink ack/nack
434 */
435 ptr_block = rd_set_acknack();
436 sig_rd_meas_qual_rpt_sent( );
437 grlc_data->tbf_ctrl[grlc_data->dl_index].ack_cnt++;
438
439 if( grlc_data->rd.ack_ctrl.cnt_meas_rpt > 0 )
440 grlc_data->rd.ack_ctrl.cnt_meas_rpt--;
441
442 if( grlc_data->rd.ack_ctrl.cnt_other > 0 )
443 grlc_data->rd.ack_ctrl.cnt_other--;
444
445 grlc_send_normal_burst(ptr_block, NULL, i);
446 }
447 else
448 {
449 /*
450 * unacknowledged mode, send packet control acknowledgment
451 */
452 if(grlc_data->burst_type EQ CGRLC_BURST_TYPE_NB)
453 {
454 ptr_block = grlc_set_packet_ctrl_ack();
455 grlc_send_normal_burst(ptr_block, NULL, i);
456 }
457 else
458 {
459 /* send access burst. */
460 grlc_send_access_burst(i);
461 }
462 }
463 grlc_data->rd.next_poll_block = NEXT_POLL_BLOCK_CTRL;
464 if(grlc_data->rd.f_ack_ind)
465 {
466 grlc_data->rd.release_tbf = TRUE;
467 }
468 }
469 else
470 {
471 /*
472 * sent control block
473 */
474 ptr_block = tm_get_ctrl_blk( &index, TRUE );
475 grlc_send_normal_burst(NULL, ptr_block, i);
476 grlc_data->rd.next_poll_block = NEXT_POLL_BLOCK_DL_DATA;
477
478 if( grlc_data->rd.ack_ctrl.cnt_meas_rpt EQ 0 )
479 grlc_data->rd.ack_ctrl.cnt_meas_rpt = ACK_CNT_NORMAL;
480
481 if( grlc_data->rd.ack_ctrl.cnt_other EQ 0 )
482 grlc_data->rd.ack_ctrl.cnt_other = ACK_CNT_NORMAL;
483 }
484 }
485 i++;
486 }
487 }
488 grlc_send_rem_poll_pos(mac_dl_ready_ind->fn);
489 break;
490 case RD_NET_REL:
491 /*
492 * send packet control acknowledgement and abort TBF
493 */
494 grlc_send_rem_poll_pos(mac_dl_ready_ind->fn);
495 if(grlc_data->rd.release_tbf)
496 {
497 SET_STATE(RD,RD_NULL);
498 grlc_data->rd.release_tbf = FALSE;
499 TRACE_EVENT_P2("poll sent after packet tbf release(DL): current_fn=%ld rel_fn=%ld",
500 mac_dl_ready_ind->fn,
501 grlc_data->rd.fn_p_tbf_rel);
502 sig_rd_tm_end_of_tbf(FALSE);
503 }
504 if(grlc_check_if_tbf_start_is_elapsed ( grlc_data->rd.fn_p_tbf_rel, mac_dl_ready_ind->fn))
505 {
506 grlc_data->rd.release_tbf = TRUE;
507 TRACE_EVENT_P2("wait for poll confirm after packet tbf release(DL) current_fn=%ld rel_fn=%ld",
508 mac_dl_ready_ind->fn,
509 grlc_data->rd.fn_p_tbf_rel);
510 }
511 break;
512 default:
513 TRACE_ERROR( "SIG_GFF_RD_MAC_READY_IND unexpected" );
514 break;
515 }
516 } /* sig_gff_rd_mac_ready_ind() */
517
518
519
520
521 /*
522 +------------------------------------------------------------------------------
523 | Function : sig_gff_rd_data
524 +------------------------------------------------------------------------------
525 | Description : Handles the SIGNAL sig_gff_rd_data
526 |
527 | Parameters : fn - current frame number
528 | tn - current timeslot number
529 | block_status - current block_status
530 | sp - sp bit of mac header.
531 | bsn - bsn number
532 | fbi - fbi bit
533 | e_bit - e bit
534 | ptr_dl_block - pointer to the dl data block
535 +------------------------------------------------------------------------------
536 */
537 GLOBAL void sig_gff_rd_data (ULONG fn, UBYTE tn, USHORT block_status,UBYTE rrbp,UBYTE sp,UBYTE bsn,UBYTE fbi,UBYTE e_bit, UBYTE * ptr_dl_block)
538 {
539 UBYTE bsn_l;
540 UBYTE diff;
541 BOOL InRange;
542 BOOL li_correct;
543 T_CODING_SCHEME old_cs_type;
544
545
546 TRACE_FUNCTION( "sig_gff_rd_data" );
547
548
549 grlc_data->tbf_ctrl[grlc_data->dl_index].cnt_ts++;
550
551
552 /*
553 * TESTMODE B
554 */
555 if (grlc_data->testmode.mode EQ CGRLC_LOOP)
556 {
557 /*
558 * If the downlink TBF is established on more than one timeslot, the MS shall transmit in
559 * the second uplink timeslot (if present) RLC/MAC blocks received on the second downlink
560 * timeslot, and shall transmit in the third uplink timeslot (if present) RLC/MAC blocks
561 * received in the third downlink timeslot and so on.
562 */
563 if (grlc_data->downlink_tbf.nts > 1)
564 {
565 if (tn - grlc_data->testmode.dl_ts_offset)
566 {
567 grlc_data->testmode.rec_data[1].block_status = block_status;
568 grlc_data->testmode.rec_data[1].e_bit = e_bit;
569 memcpy(grlc_data->testmode.rec_data[1].payload,ptr_dl_block,50);
570 }
571 else
572 {
573 grlc_data->testmode.rec_data[0].block_status = block_status;
574 grlc_data->testmode.rec_data[0].e_bit = e_bit;
575 memcpy(grlc_data->testmode.rec_data[0].payload,ptr_dl_block,50);
576 }
577 }
578 else
579 {
580 grlc_data->testmode.rec_data[0].block_status = block_status;
581 grlc_data->testmode.rec_data[0].e_bit = e_bit;
582 memcpy(grlc_data->testmode.rec_data[0].payload,ptr_dl_block,50);
583 }
584
585 grlc_data->rd.f_ack_ind = rd_check_fbi(fbi,sp,fn,rrbp);
586
587 vsi_t_stop(GRLC_handle,T3190);
588 vsi_t_start(GRLC_handle,T3190,T3190_VALUE);
589
590 TRACE_EVENT_P6("DL DATA in testmode B at fn=%ld: bsn =%d, bs=%d,e_bit=%d, fbi=%d sp=%d "
591 ,fn
592 ,bsn
593 ,block_status
594 ,grlc_data->testmode.rec_data[0].e_bit
595 ,fbi
596 ,sp);
597 return;
598 }
599
600
601
602
603 /******************************************************************************************/
604 #if defined (_SIMULATION_)
605 TRACE_EVENT_P1("DL DATA bsn= %d",bsn);
606 #endif /* defined (_SIMULATION_) */
607
608
609 if(grlc_data->rd.vq NEQ grlc_data->rd.vr)
610 {
611 TRACE_EVENT_P5("wait for neg acked blocks :bsn=%d vr=%d vq=%d fbi=%d fn=%ld",
612 bsn,
613 grlc_data->rd.vr,
614 grlc_data->rd.vq,
615 fbi,
616 fn);
617 }
618 /******************************************************************************************/
619 old_cs_type = grlc_data->rd.cs_type;
620 switch( GET_STATE( RD ) )
621 {
622 case RD_WAIT_FOR_STARTING_TIME_ACK:
623 SET_STATE(RD,RD_ACK);
624
625 /*lint -fallthrough*/
626
627 case RD_ACK :
628 vsi_t_stop(GRLC_handle,T3190);
629 vsi_t_start(GRLC_handle,T3190,T3190_VALUE);
630 bsn_l = bsn;
631 InRange = rd_check_window_size(bsn_l);
632
633
634 if( !InRange OR (grlc_data->rd.vn[bsn_l & WIN_MOD] EQ VN_RECEIVED))
635 {
636 grlc_data->tbf_ctrl[grlc_data->dl_index].ret_bsn++;
637
638 if( fbi AND
639 !grlc_data->rd.f_ack_ind AND
640 ((bsn_l+1) & 0x7F) EQ grlc_data->rd.vr)
641 { /* WORKAROUND FOR NORTEL, fbi bit is modified , only possible for last bsn*/
642
643 grlc_data->rd.f_ack_ind=rd_check_fbi(fbi,sp,fn,rrbp);
644
645 TRACE_EVENT_P8("fbi modification in ret bsn=%d,vr=%d,vq=%d,sp=%d,fbi=%d,e=%d ptr[0]=%x,ptr[1]=%x",
646 bsn_l,
647 grlc_data->rd.vr,
648 grlc_data->rd.vq,
649 sp,
650 fbi,
651 e_bit,
652 ptr_dl_block[0],
653 ptr_dl_block[1]);
654
655 }
656
657 return;
658 }
659 grlc_data->rd.rlc_data_len = rd_calc_rlc_data_len(block_status);
660 li_correct = rd_read_li_m_of_block(ptr_dl_block,
661 e_bit);
662 if((old_cs_type NEQ grlc_data->rd.cs_type) AND
663 (old_cs_type NEQ CS_ZERO))
664 {
665 TRACE_EVENT_P3("DL CS TYPE CHANGED from %d to %d, bsn=%d",old_cs_type,grlc_data->rd.cs_type,bsn_l);
666 }
667
668 if(!li_correct)
669 {
670 grlc_data->rd.vn[bsn_l & WIN_MOD] = VN_INVALID;
671 TRACE_ERROR( "LI field is longer than RLC data block" );
672 return;
673 }
674
675 /*
676 * compute receive parameter
677 */
678 rd_comp_rec_par(bsn_l);
679
680 rd_save_block( bsn_l, &(ptr_dl_block[grlc_data->rd.li_cnt]),
681 fbi );
682
683 #if defined (_SIMULATION_)
684 TRACE_EVENT_P1("first_ptr= %ld",grlc_data->rd.data_array[bsn_l & WIN_MOD].first);
685 #endif /* defined (_SIMULATION_) */
686
687 diff = (grlc_data->rd.vq - bsn_l) & 0x7F;
688 while( ( diff <= WIN_SIZE) AND
689 (grlc_data->rd.vq NEQ bsn_l) AND
690 (grlc_data->rd.vn[bsn_l & WIN_MOD] EQ VN_RECEIVED ) )
691 {
692 rd_send_grlc_data_ind(bsn_l);
693 bsn_l = (bsn_l+1) & 0x7F;
694 diff = (grlc_data->rd.vq - bsn_l) & 0x7F;
695 }
696
697 grlc_data->rd.f_ack_ind = rd_check_fbi(fbi,sp,fn,rrbp);
698
699 break;
700 case RD_REL_ACK :
701 /*
702 * all blocks are received, after sending p. dl ack nack timer t3192 will be restarted
703 */
704 grlc_data->tbf_ctrl[grlc_data->dl_index].ret_bsn++;
705
706 if(grlc_data->rd.f_ack_ind AND sp)
707 { /*
708 * will be restarted at sending the dl ack nack: secure, in case of gaps.
709 * The value could be zero, therfore a offset is needed
710 */
711 vsi_t_stop(GRLC_handle,T3192);
712 grlc_data->rd.fn_p_tbf_rel = grlc_decode_tbf_start_rel(fn,(USHORT)(rrbp+3));
713 TRACE_EVENT_P3("FINAL DL ACK RETR REQIURED t3192=%d rel_fn=%ld c_fn=%ld ",grlc_data->downlink_tbf.t3192_val,grlc_data->rd.fn_p_tbf_rel,fn);
714 }
715 /* TRACE_EVENT_P7("BLOCK DISCARDED WAIT FOR TBF RELEASE f_ack=%d bsn=%d sp=%d rrbp=%d vr=%d vq=%d t3192=%d"
716 ,grlc_data->rd.f_ack_ind
717 ,bsn
718 ,sp
719 ,rrbp
720 ,grlc_data->rd.vr
721 ,grlc_data->rd.vq
722 ,grlc_data->downlink_tbf.t3192_val);
723 */
724 break;
725 case RD_WAIT_FOR_STARTING_TIME_UACK:
726 SET_STATE(RD,RD_UACK);
727
728 /*lint -fallthrough*/
729
730 case RD_UACK:
731 /*
732 * After receiving each block the timer T3190 should be restarted.
733 */
734 vsi_t_stop(GRLC_handle,T3190);
735 vsi_t_start(GRLC_handle,T3190,T3190_VALUE);
736
737 if(!rd_check_window_size(bsn))
738 {
739 TRACE_EVENT_P3("UACK bsn outside window: bsn=%d vr=%d vq=%d",bsn,grlc_data->rd.vr,grlc_data->rd.vq);
740 return;
741 }
742
743 grlc_data->rd.rlc_data_len = rd_calc_rlc_data_len(block_status);
744 li_correct = rd_read_li_m_of_block(ptr_dl_block, e_bit);
745 if(!li_correct)
746 {
747 TRACE_ERROR( "LI field is longer than RLC data block" );
748 return;
749 }
750
751 /*
752 * compute receive parameter
753 */
754 rd_comp_rec_par(bsn);
755 rd_save_block( bsn, &(ptr_dl_block[grlc_data->rd.li_cnt]), fbi );
756 if(!grlc_data->rd.inSequence)
757 rd_fill_blocks(bsn);
758
759 rd_send_grlc_data_ind(bsn);
760
761 grlc_data->rd.f_ack_ind = rd_check_fbi(fbi,sp,fn,rrbp);
762
763 break;
764 case RD_REL_UACK:
765
766 if(fbi AND sp)
767 {
768 vsi_t_stop(GRLC_handle,T3192);
769 grlc_data->rd.fn_p_tbf_rel = grlc_decode_tbf_start_rel(fn,(USHORT)(rrbp+3));
770 TRACE_EVENT_P4("data in REL_UACK restart t3192: bsn=%d t3192=%d fn=%ld rel_fn=%ld"
771 ,bsn
772 ,grlc_data->downlink_tbf.t3192_val
773 ,fn
774 ,grlc_data->rd.fn_p_tbf_rel);
775
776 }
777 break;
778 default:
779 TRACE_ERROR( "SIG_GFF_RD_DATA unexpected" );
780 break;
781 }
782
783 } /* sig_gff_rd_data() */
784
785 /*
786 +------------------------------------------------------------------------------
787 | Function : sig_ru_rd_get_downlink_release_state
788 +------------------------------------------------------------------------------
789 | Description : This function returns true if RD is in release state( if
790 | fbi=1 is received in dowonlink data block.
791 |
792 | Parameters : release_state
793 +------------------------------------------------------------------------------
794 */
795 GLOBAL void sig_ru_rd_get_downlink_release_state( BOOL *release_started)
796 {
797 *release_started = FALSE ;
798
799 if( (GET_STATE( RD ) EQ RD_REL_ACK ) OR
800 (GET_STATE( RD ) EQ RD_REL_UACK ) )
801 {
802 *release_started = TRUE;
803 }
804 else if(GET_STATE( RD ) EQ RD_NULL )
805 {
806 TRACE_ERROR("ERROR:sig_ru_rd_get_downlink_release_state called in RD NULL state");
807 *release_started = TRUE;
808 }
809 }