FreeCalypso > hg > fc-tourmaline
comparison src/g23m-gprs/grlc/grlc_rds.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 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 } |