FreeCalypso > hg > fc-tourmaline
comparison src/g23m-gprs/grlc/grlc_rdf.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 RD of | |
18 | entity GRLC. | |
19 +----------------------------------------------------------------------------- | |
20 */ | |
21 | |
22 #ifndef GRLC_RDF_C | |
23 #define GRLC_RDF_C | |
24 #endif | |
25 | |
26 #define ENTITY_GRLC | |
27 | |
28 /*==== INCLUDES =============================================================*/ | |
29 | |
30 #include "typedefs.h" /* to get Condat data types */ | |
31 #include "vsi.h" /* to get a lot of macros */ | |
32 #include "macdef.h" | |
33 #include "gprs.h" | |
34 #include "gsm.h" /* to get a lot of macros */ | |
35 #include "ccdapi.h" /* to get CCD API */ | |
36 #include "cnf_grlc.h" /* to get cnf-definitions */ | |
37 #include "mon_grlc.h" /* to get mon-definitions */ | |
38 #include "prim.h" /* to get the definitions of used SAP and directions */ | |
39 #include "message.h" | |
40 #include "grlc.h" /* to get the global entity definitions */ | |
41 #include "grlc_tms.h" | |
42 #include <string.h> /* memcpy */ | |
43 #include "grlc_f.h" | |
44 #include "grlc_rdf.h" | |
45 #include "grlc_meass.h" | |
46 | |
47 /*==== CONST ================================================================*/ | |
48 | |
49 /*==== LOCAL VARS ===========================================================*/ | |
50 | |
51 /*==== PRIVATE FUNCTIONS ====================================================*/ | |
52 | |
53 /*==== PUBLIC FUNCTIONS =====================================================*/ | |
54 | |
55 | |
56 /* | |
57 +------------------------------------------------------------------------------ | |
58 | Function : rd_init | |
59 +------------------------------------------------------------------------------ | |
60 | Description : The function rd_init() .... | |
61 | | |
62 | Parameters : dummy - description of parameter dummy | |
63 | | |
64 +------------------------------------------------------------------------------ | |
65 */ | |
66 GLOBAL void rd_init ( void ) | |
67 { | |
68 TRACE_FUNCTION( "rd_init" ); | |
69 | |
70 /* | |
71 * UBYTE | |
72 */ | |
73 grlc_data->rd.vq = 0xFF; | |
74 grlc_data->rd.vr = 0xFF; | |
75 grlc_data->rd.li_cnt = 0xFF; | |
76 grlc_data->rd.rlc_data_len = 0xFF; | |
77 grlc_data->rd.f_ack_ind = 0xFF; | |
78 grlc_data->rd.ssn = 0xFF; | |
79 | |
80 /* | |
81 * USHORT | |
82 */ | |
83 grlc_data->rd.pdu_len = 0xFFFF; | |
84 /* | |
85 * BOOL | |
86 */ | |
87 grlc_data->rd.pdu_complete = TRUE; | |
88 grlc_data->rd.channel_req = FALSE; | |
89 grlc_data->rd.ch_req_in_ack_prog = FALSE; | |
90 grlc_data->rd.inSequence = TRUE; | |
91 /* | |
92 * struct | |
93 */ | |
94 grlc_data->rd.ptr_grlc = NULL; | |
95 grlc_data->rd.next_poll_block = NEXT_POLL_BLOCK_NONE; | |
96 | |
97 INIT_STATE(RD,RD_NULL); | |
98 | |
99 } /* rd_init() */ | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 /* | |
106 +------------------------------------------------------------------------------ | |
107 | Function : rd_tbf_init | |
108 +------------------------------------------------------------------------------ | |
109 | Description : The function rd_tbf_init() .... | |
110 | | |
111 | Parameters : dummy - description of parameter dummy | |
112 | | |
113 +------------------------------------------------------------------------------ | |
114 */ | |
115 GLOBAL void rd_tbf_init ( void ) | |
116 { | |
117 TRACE_FUNCTION( "rd_tbf_init" ); | |
118 | |
119 /* | |
120 * UBYTE | |
121 */ | |
122 grlc_data->rd.vq = 0; | |
123 grlc_data->rd.vr = 0; | |
124 grlc_data->rd.li_cnt = 0; | |
125 grlc_data->rd.ssn = 0; | |
126 grlc_data->rd.last_bsn = 0xFF; | |
127 grlc_data->rd.bsn_pdu_start = 0xFF; /*set to zero at receiving the first data block*/ | |
128 grlc_data->rd.cnt_sent_f_ack = 0; | |
129 grlc_data->rd.f_ack_ind = 0; | |
130 grlc_data->dl_tn_mask = grlc_data->downlink_tbf.ts_mask; | |
131 | |
132 /* | |
133 * USHORT | |
134 */ | |
135 grlc_data->rd.pdu_len = 0; | |
136 | |
137 /* | |
138 * BOOL | |
139 */ | |
140 grlc_data->rd.release_tbf = FALSE; | |
141 grlc_data->rd.pdu_complete = TRUE; | |
142 grlc_data->rd.ch_req_in_ack_prog = FALSE; | |
143 grlc_data->rd.v_next_tbf_params = FALSE; | |
144 grlc_data->rd.ignore_pdu = FALSE; | |
145 | |
146 | |
147 grlc_data->rd.fn_p_tbf_rel = 0xFFFFFFFF; | |
148 /* | |
149 * struct | |
150 */ | |
151 grlc_data->rd.rlc_mode = grlc_data->downlink_tbf.rlc_mode; | |
152 grlc_data->rd.cs_type = CS_ZERO; | |
153 /* | |
154 * arrays | |
155 */ | |
156 | |
157 memset(grlc_data->rd.data_array, 0 , WIN_SIZE * sizeof(grlc_data->rd.data_array[0]) ); | |
158 memset(grlc_data->rd.vn , VN_INVALID, WIN_SIZE * sizeof(grlc_data->rd.vn[0]) ); | |
159 memset(grlc_data->rd.li , 0 , RD_LI_CNT_MAX * sizeof(grlc_data->rd.li[0]) ); | |
160 memset(grlc_data->rd.m , 0 , RD_LI_CNT_MAX ); | |
161 | |
162 } /* rd_tbf_init() */ | |
163 | |
164 | |
165 | |
166 /* | |
167 +------------------------------------------------------------------------------ | |
168 | Function : rd_read_li_m_of_block | |
169 +------------------------------------------------------------------------------ | |
170 | Description : The function rd_read_li_m_of_block() .... | |
171 | | |
172 | Parameters : dummy - description of parameter dummy | |
173 | | |
174 +------------------------------------------------------------------------------ | |
175 */ | |
176 GLOBAL BOOL rd_read_li_m_of_block ( UBYTE * ptr_data_i, UBYTE e_bit_i ) | |
177 { | |
178 USHORT len_sum; | |
179 BOOL result; | |
180 | |
181 TRACE_FUNCTION( "rd_read_li_m_of_block" ); | |
182 | |
183 len_sum = 0; | |
184 grlc_data->rd.li_cnt = 0; | |
185 | |
186 while(!(e_bit_i)) | |
187 { | |
188 grlc_data->rd.li[grlc_data->rd.li_cnt] = | |
189 (ptr_data_i[grlc_data->rd.li_cnt] & 0xFC) >> 2; | |
190 grlc_data->rd.m [grlc_data->rd.li_cnt] = | |
191 (ptr_data_i[grlc_data->rd.li_cnt] & 0x02) >> 1; | |
192 e_bit_i = (ptr_data_i[grlc_data->rd.li_cnt] & 0x01); | |
193 len_sum += grlc_data->rd.li[grlc_data->rd.li_cnt]; | |
194 if((e_bit_i EQ 0) | |
195 AND (!grlc_data->rd.m [grlc_data->rd.li_cnt])) | |
196 { | |
197 /*SZML-RD/001*/ | |
198 return FALSE; | |
199 } | |
200 else if(!(grlc_data->rd.li[grlc_data->rd.li_cnt]) | |
201 AND (grlc_data->rd.m [grlc_data->rd.li_cnt])) | |
202 { | |
203 TRACE_ERROR("dl block with li=0 and m=1: NOT ALLOWED"); | |
204 return FALSE; | |
205 } | |
206 grlc_data->rd.li_cnt++; | |
207 } | |
208 | |
209 if(grlc_data->rd.li_cnt > RD_LI_CNT_MAX) | |
210 { | |
211 TRACE_EVENT_P2("li_cnt=%d RD_LI_CNT_MAX=%d",grlc_data->rd.li_cnt,RD_LI_CNT_MAX); | |
212 TRACE_ERROR("rd li_cnt bigger than RD_LI_CNT_MAX (=8)"); | |
213 TRACE_ASSERT( grlc_data->rd.li_cnt > RD_LI_CNT_MAX ); | |
214 return FALSE; | |
215 } | |
216 | |
217 /* | |
218 * check if sum of LIs is longer than a rlc data block len | |
219 */ | |
220 len_sum += grlc_data->rd.li_cnt; | |
221 if( (len_sum > grlc_data->rd.rlc_data_len) | |
222 OR | |
223 ((len_sum EQ grlc_data->rd.rlc_data_len) AND (grlc_data->rd.m [grlc_data->rd.li_cnt-1])) ) | |
224 result = FALSE; | |
225 else | |
226 result = TRUE; | |
227 | |
228 return result; | |
229 | |
230 } /* rd_read_li_m_of_block() */ | |
231 | |
232 | |
233 | |
234 /* | |
235 +------------------------------------------------------------------------------ | |
236 | Function : rd_out_grlc_data_ind | |
237 +------------------------------------------------------------------------------ | |
238 | Description : The function rd_out_grlc_data_ind() .... | |
239 | | |
240 | Parameters : dummy - description of parameter dummy | |
241 | | |
242 +------------------------------------------------------------------------------ | |
243 */ | |
244 GLOBAL void rd_out_grlc_data_ind( void ) | |
245 { | |
246 T_GRLC_DATA_IND *prim_ptr; | |
247 TRACE_FUNCTION( "rd_out_grlc_data_ind" ); | |
248 | |
249 if(grlc_data->rd.ignore_pdu OR | |
250 grlc_test_mode_active()) | |
251 { | |
252 /* | |
253 * this pdu is not passed to LLC because MAX_LLC_PDU_SIZE was exceed or testmode is active | |
254 */ | |
255 grlc_data->rd.ignore_pdu = FALSE; | |
256 | |
257 TRACE_EVENT_P4("TARGET PDU END reached at will be ignored: len=%ld, bsn=pdu_start=%d vr = %d testmode=%d " | |
258 ,grlc_data->rd.pdu_len | |
259 ,grlc_data->rd.bsn_pdu_start | |
260 ,grlc_data->rd.vr | |
261 ,grlc_test_mode_active()); | |
262 | |
263 rd_free_desc_list_partions(); | |
264 return; | |
265 } | |
266 | |
267 if(grlc_data->rd.rlc_mode EQ CGRLC_RLC_MODE_ACK) | |
268 { | |
269 PALLOC_DESC (grlc_data_ind, GRLC_DATA_IND);//lint !e413 | |
270 prim_ptr = grlc_data_ind; | |
271 } | |
272 else | |
273 { | |
274 PALLOC_DESC (grlc_unitdata_ind, GRLC_UNITDATA_IND);//lint !e413 | |
275 prim_ptr = (T_GRLC_DATA_IND*)grlc_unitdata_ind; | |
276 } | |
277 | |
278 memcpy( prim_ptr, | |
279 &grlc_data->rd.grlc_data_ind, | |
280 sizeof(T_GRLC_DATA_IND) ); | |
281 PSEND(hCommLLC, prim_ptr); | |
282 | |
283 grlc_data->rd.grlc_data_ind.desc_list.first = NULL; | |
284 grlc_data->rd.pdu_complete = TRUE; | |
285 grlc_data->tbf_ctrl[grlc_data->dl_index].rlc_oct_cnt += grlc_data->rd.pdu_len; | |
286 grlc_data->tbf_ctrl[grlc_data->dl_index].pdu_cnt++; | |
287 | |
288 } /* rd_out_grlc_data_ind() */ | |
289 | |
290 #ifdef _SIMULATION_ | |
291 | |
292 /* | |
293 +------------------------------------------------------------------------------ | |
294 | Function : rd_out_grlc_data_ind_test | |
295 +------------------------------------------------------------------------------ | |
296 | Description : The function rd_out_grlc_data_ind_test() .... | |
297 | | |
298 | Parameters : dummy - description of parameter dummy | |
299 | | |
300 +------------------------------------------------------------------------------ | |
301 */ | |
302 GLOBAL void rd_out_grlc_data_ind_test( void ) | |
303 { | |
304 T_NEXT_ARRAY *ptr_next_array = NULL; | |
305 T_NEXT_ARRAY *ptr_help = NULL; | |
306 UBYTE *ptr_pos = NULL,cnt=0; | |
307 USHORT sdu_len_in_bits; | |
308 T_GRLC_DATA_IND_TEST *prim_ptr = NULL; | |
309 | |
310 TRACE_FUNCTION( "rd_out_grlc_data_ind_test" ); | |
311 | |
312 | |
313 if(grlc_data->rd.ignore_pdu OR | |
314 grlc_test_mode_active()) | |
315 { | |
316 /* | |
317 * this pdu is not passed to LLC because MAX_LLC_PDU_SIZE was exceed or testmode is active | |
318 */ | |
319 grlc_data->rd.ignore_pdu = FALSE; | |
320 | |
321 TRACE_EVENT_P4("SIMULATION PDU END reached at will be ignored: len=%ld, bsn=pdu_start=%d vr = %d testmode=%d" | |
322 ,grlc_data->rd.pdu_len | |
323 ,grlc_data->rd.bsn_pdu_start | |
324 ,grlc_data->rd.vr | |
325 ,grlc_test_mode_active()); | |
326 rd_free_desc_list_partions(); | |
327 return; | |
328 } | |
329 sdu_len_in_bits = grlc_data->rd.pdu_len * 8; | |
330 | |
331 if(grlc_data->rd.rlc_mode EQ CGRLC_RLC_MODE_ACK) | |
332 { | |
333 PALLOC_SDU (grlc_data_ind_test, GRLC_DATA_IND_TEST, sdu_len_in_bits); | |
334 prim_ptr = grlc_data_ind_test; | |
335 } | |
336 else | |
337 { | |
338 PALLOC_SDU (grlc_unitdata_ind_test, GRLC_UNITDATA_IND_TEST, sdu_len_in_bits); | |
339 prim_ptr = (T_GRLC_DATA_IND_TEST*)grlc_unitdata_ind_test; | |
340 } | |
341 { | |
342 /* | |
343 * copy from description list to test primitive | |
344 */ | |
345 prim_ptr->tlli = grlc_data->downlink_tbf.tlli; | |
346 prim_ptr->sdu.l_buf = grlc_data->rd.pdu_len * 8; | |
347 prim_ptr->sdu.o_buf = 0; | |
348 ptr_next_array = | |
349 (T_NEXT_ARRAY*)grlc_data->rd.grlc_data_ind.desc_list.first; | |
350 ptr_pos = prim_ptr->sdu.buf; | |
351 cnt=0; | |
352 do | |
353 { | |
354 cnt++; | |
355 memcpy(ptr_pos, | |
356 ptr_next_array->data, | |
357 ptr_next_array->len ); | |
358 ptr_pos = &ptr_pos[ptr_next_array->len]; | |
359 ptr_next_array = (T_NEXT_ARRAY*)ptr_next_array->next; | |
360 } | |
361 while(ptr_next_array NEQ NULL); | |
362 PSEND(hCommLLC, prim_ptr); | |
363 TRACE_EVENT_P1("SEND PARTIONS =%d",cnt); | |
364 | |
365 } | |
366 | |
367 grlc_data->tbf_ctrl[grlc_data->dl_index].rlc_oct_cnt += grlc_data->rd.pdu_len; | |
368 grlc_data->tbf_ctrl[grlc_data->dl_index].pdu_cnt++; | |
369 | |
370 | |
371 /* delete blocks which are sent to LLC: only possible in test environment | |
372 * usally, deleting of the description list is task of LLC | |
373 */ | |
374 rd_free_desc_list_partions(); | |
375 | |
376 } /* rd_out_grlc_data_ind_test() */ | |
377 | |
378 #endif /* _SIMULATION_ */ | |
379 | |
380 | |
381 | |
382 | |
383 /* | |
384 +------------------------------------------------------------------------------ | |
385 | Function : rd_send_grlc_data_ind | |
386 +------------------------------------------------------------------------------ | |
387 | Description : The function rd_send_grlc_data_ind() .... | |
388 | | |
389 | Parameters : dummy - description of parameter dummy | |
390 | | |
391 +------------------------------------------------------------------------------ | |
392 */ | |
393 GLOBAL void rd_send_grlc_data_ind ( UBYTE bsn_i ) | |
394 { | |
395 T_NEXT_ARRAY *ptr_block; | |
396 UBYTE pdu_cnt; | |
397 UBYTE compl_pdu; | |
398 TRACE_FUNCTION( "rd_send_grlc_data_ind" ); | |
399 | |
400 | |
401 pdu_cnt = grlc_data->rd.data_array[bsn_i & WIN_MOD].pdu_cnt; | |
402 | |
403 if(grlc_data->rd.data_array[bsn_i & WIN_MOD].pdu_complete) | |
404 compl_pdu = grlc_data->rd.data_array[bsn_i & WIN_MOD].pdu_cnt; | |
405 else if (pdu_cnt) | |
406 compl_pdu = grlc_data->rd.data_array[bsn_i & WIN_MOD].pdu_cnt -1; | |
407 else | |
408 compl_pdu = 0; | |
409 | |
410 if ((ptr_block = grlc_data->rd.data_array[bsn_i & WIN_MOD].first) EQ NULL) | |
411 { | |
412 TRACE_EVENT_P4("NO DATA IND first empty bsn=%d bsn_mod=%d vr=%d vq=%d", bsn_i, bsn_i&WIN_MOD,grlc_data->rd.vr,grlc_data->rd.vq); | |
413 return; | |
414 } | |
415 | |
416 do | |
417 { | |
418 if(grlc_data->rd.pdu_complete) | |
419 { | |
420 grlc_data->rd.ptr_grlc = ptr_block; | |
421 grlc_data->rd.grlc_data_ind.desc_list.first = (ULONG) grlc_data->rd.ptr_grlc; | |
422 grlc_data->rd.pdu_len = ptr_block->len; | |
423 grlc_data->rd.bsn_pdu_start = bsn_i; | |
424 } | |
425 else | |
426 { | |
427 grlc_data->rd.pdu_len += ptr_block->len; | |
428 grlc_data->rd.ptr_grlc->next = (ULONG*) ptr_block; | |
429 grlc_data->rd.ptr_grlc = (T_NEXT_ARRAY*) grlc_data->rd.ptr_grlc->next; | |
430 } | |
431 grlc_data->rd.pdu_complete = FALSE; | |
432 | |
433 if(grlc_data->rd.pdu_len > MAX_LLC_PDU_SIZE) | |
434 { | |
435 TRACE_EVENT_P5("PDU SIZE TO BIG = %ld pdu_st=%d vr=%d compl_pdu=%d pdu_cnt=%d" | |
436 ,grlc_data->rd.pdu_len | |
437 ,grlc_data->rd.bsn_pdu_start | |
438 ,grlc_data->rd.vr | |
439 ,compl_pdu | |
440 ,pdu_cnt); | |
441 if(!compl_pdu) | |
442 { | |
443 /* no pdu in data block */ | |
444 grlc_data->rd.ignore_pdu = TRUE; | |
445 | |
446 /* free only linked partions */ | |
447 rd_free_desc_list_partions(); | |
448 | |
449 return; | |
450 } | |
451 else | |
452 { | |
453 /* pdu boundary in data block */ | |
454 ptr_block = (T_NEXT_ARRAY*) ptr_block->next; | |
455 grlc_data->rd.ptr_grlc->next = NULL; | |
456 | |
457 /* | |
458 * free only linked partions | |
459 */ | |
460 rd_free_desc_list_partions(); | |
461 | |
462 compl_pdu--; | |
463 } | |
464 | |
465 } | |
466 else if( compl_pdu ) | |
467 { | |
468 | |
469 TRACE_EVENT_P5("GRLC_DATA_IND len=%ld bsn_start=%d bsn_end=%d las_len=%d dl_fn=%ld" | |
470 | |
471 | |
472 | |
473 | |
474 | |
475 | |
476 | |
477 | |
478 | |
479 | |
480 | |
481 | |
482 | |
483 | |
484 | |
485 | |
486 | |
487 | |
488 | |
489 | |
490 | |
491 ,grlc_data->rd.pdu_len | |
492 ,grlc_data->rd.bsn_pdu_start | |
493 ,bsn_i | |
494 ,ptr_block->len | |
495 ,grlc_data->dl_fn); | |
496 ptr_block = (T_NEXT_ARRAY*) ptr_block->next; | |
497 grlc_data->rd.ptr_grlc->next = NULL; | |
498 grlc_data->rd.grlc_data_ind.desc_list.list_len = grlc_data->rd.pdu_len; | |
499 grlc_data->rd.grlc_data_ind.tlli = grlc_data->downlink_tbf.tlli; | |
500 | |
501 #ifdef _TARGET_ | |
502 { | |
503 rd_out_grlc_data_ind(); | |
504 } | |
505 # endif | |
506 | |
507 # ifdef _SIMULATION_ | |
508 { | |
509 rd_out_grlc_data_ind_test(); | |
510 } | |
511 # endif | |
512 grlc_data->rd.pdu_complete = TRUE; | |
513 compl_pdu--; | |
514 } | |
515 if(!pdu_cnt) | |
516 pdu_cnt = 0; | |
517 else | |
518 pdu_cnt--; | |
519 } | |
520 while(pdu_cnt); | |
521 | |
522 grlc_data->rd.pdu_complete = grlc_data->rd.data_array[bsn_i & WIN_MOD].pdu_complete; | |
523 | |
524 /* | |
525 * block combined, first element reseted | |
526 */ | |
527 grlc_data->rd.data_array[bsn_i & WIN_MOD].first = NULL; | |
528 | |
529 } /* rd_send_grlc_data_ind() */ | |
530 | |
531 | |
532 | |
533 /* | |
534 +------------------------------------------------------------------------------ | |
535 | Function : rd_check_window_size | |
536 +------------------------------------------------------------------------------ | |
537 | Description : The function rd_check_window_size() .... | |
538 | | |
539 | Parameters : dummy - description of parameter dummy | |
540 | | |
541 +------------------------------------------------------------------------------ | |
542 */ | |
543 GLOBAL BOOL rd_check_window_size ( UBYTE bsn_i ) | |
544 { | |
545 BOOL result; | |
546 | |
547 TRACE_FUNCTION( "rd_check_window_size" ); | |
548 | |
549 if(grlc_data->rd.rlc_mode EQ CGRLC_RLC_MODE_ACK) | |
550 { | |
551 if( bsn_i >= grlc_data->rd.ssn ) | |
552 { | |
553 if((bsn_i - grlc_data->rd.ssn) < WIN_SIZE) | |
554 { | |
555 result = TRUE; | |
556 } | |
557 else | |
558 { | |
559 result = FALSE; | |
560 } | |
561 } | |
562 else | |
563 { | |
564 if((bsn_i + 128 - grlc_data->rd.ssn) < WIN_SIZE) | |
565 { | |
566 result = TRUE; | |
567 } | |
568 else | |
569 { | |
570 result = FALSE; | |
571 } | |
572 } | |
573 } | |
574 else if(grlc_data->rd.rlc_mode EQ CGRLC_RLC_MODE_UACK) | |
575 { | |
576 if( bsn_i >= grlc_data->rd.vr ) | |
577 { | |
578 if((bsn_i - grlc_data->rd.vr) < WIN_SIZE) | |
579 { | |
580 result = TRUE; | |
581 } | |
582 else | |
583 { | |
584 result = FALSE; | |
585 } | |
586 } | |
587 else | |
588 { | |
589 if((bsn_i + 128 - grlc_data->rd.vr) < WIN_SIZE) | |
590 { | |
591 result = TRUE; | |
592 } | |
593 else | |
594 { | |
595 result = FALSE; | |
596 } | |
597 } | |
598 } | |
599 else | |
600 { | |
601 result =FALSE; | |
602 TRACE_EVENT_P4("unknown rlc mode in rd_check_window_size: rlc_mode=%d, bsn_i=%d,ssn=%d,vr=%d " | |
603 ,grlc_data->rd.rlc_mode | |
604 ,bsn_i | |
605 ,grlc_data->rd.ssn | |
606 ,grlc_data->rd.vr); | |
607 } | |
608 | |
609 | |
610 return result; | |
611 } /* rd_check_window_size() */ | |
612 | |
613 | |
614 | |
615 /* | |
616 +------------------------------------------------------------------------------ | |
617 | Function : rd_save_block | |
618 +------------------------------------------------------------------------------ | |
619 | Description : The function rd_save_block() .... | |
620 | | |
621 | Parameters : bsn_i - block sequence number of the saved block | |
622 | *ptr_data_block_i - pointer the data field of the rlc data | |
623 | block without header and li field | |
624 | fbi_i - final block indication bit of the received | |
625 | data block | |
626 | | |
627 +------------------------------------------------------------------------------ | |
628 */ | |
629 GLOBAL void rd_save_block ( UBYTE bsn_i, UBYTE * ptr_data_block_i, UBYTE fbi_i) | |
630 { | |
631 T_NEXT_ARRAY *ptr_temp=NULL; | |
632 UBYTE block_nr; | |
633 UBYTE i; | |
634 UBYTE *ptr_data; | |
635 USHORT len; | |
636 TRACE_FUNCTION( "rd_save_block" ); | |
637 | |
638 if(!(grlc_data->rd.li_cnt)) | |
639 { | |
640 /* | |
641 * only a part of a pdu | |
642 */ | |
643 MALLOC(ptr_temp, sizeof(T_NEXT_ARRAY)); | |
644 ptr_temp->next = NULL; | |
645 ptr_temp->len = grlc_data->rd.rlc_data_len; | |
646 memcpy((ptr_temp->data),(ptr_data_block_i),(ptr_temp->len)); | |
647 grlc_data->rd.data_array[bsn_i & WIN_MOD].first = ptr_temp; | |
648 if(fbi_i) | |
649 { | |
650 grlc_data->rd.data_array[bsn_i & WIN_MOD].pdu_cnt = 1; | |
651 grlc_data->rd.data_array[bsn_i & WIN_MOD].pdu_complete =TRUE; | |
652 } | |
653 else | |
654 { | |
655 grlc_data->rd.data_array[bsn_i & WIN_MOD].pdu_cnt = 0; | |
656 grlc_data->rd.data_array[bsn_i & WIN_MOD].pdu_complete =FALSE; | |
657 } | |
658 | |
659 } | |
660 else | |
661 { | |
662 /* | |
663 * for the first part | |
664 */ | |
665 MALLOC(ptr_temp, sizeof(T_NEXT_ARRAY)); | |
666 if(grlc_data->rd.li[0] EQ 0 ) | |
667 ptr_temp->len = grlc_data->rd.rlc_data_len-1; | |
668 else | |
669 ptr_temp->len = grlc_data->rd.li[0]; | |
670 | |
671 ptr_data = ptr_data_block_i; | |
672 memcpy((ptr_temp->data), | |
673 (ptr_data), | |
674 (ptr_temp->len)); | |
675 grlc_data->rd.data_array[bsn_i & WIN_MOD].first = ptr_temp; | |
676 block_nr = 1; | |
677 while((block_nr <= grlc_data->rd.li_cnt) AND (grlc_data->rd.m[block_nr-1])) | |
678 { | |
679 ptr_data = &(ptr_data[ptr_temp->len]); | |
680 MALLOC(ptr_temp->next, sizeof(T_NEXT_ARRAY)); | |
681 ptr_temp = (T_NEXT_ARRAY *)ptr_temp->next; | |
682 /* | |
683 * check if it islast pdu in rlc data block | |
684 */ | |
685 if((block_nr EQ grlc_data->rd.li_cnt) | |
686 OR (grlc_data->rd.li[block_nr] EQ 0)) | |
687 { | |
688 /* | |
689 * last block, len is REST | |
690 */ | |
691 len = 0; | |
692 for(i=0; i < grlc_data->rd.li_cnt; i++) | |
693 len += grlc_data->rd.li[i]; | |
694 ptr_temp->len = grlc_data->rd.rlc_data_len - grlc_data->rd.li_cnt - len; | |
695 } | |
696 else | |
697 { | |
698 /* | |
699 * not last part | |
700 */ | |
701 ptr_temp->len = grlc_data->rd.li[block_nr]; | |
702 } | |
703 memcpy((ptr_temp->data), | |
704 (ptr_data), | |
705 (ptr_temp->len)); | |
706 block_nr++; | |
707 } | |
708 ptr_temp->next = NULL; | |
709 if(grlc_data->rd.m[grlc_data->rd.li_cnt-1] EQ 0) | |
710 grlc_data->rd.data_array[bsn_i & WIN_MOD].pdu_cnt = grlc_data->rd.li_cnt; | |
711 else | |
712 grlc_data->rd.data_array[bsn_i & WIN_MOD].pdu_cnt = grlc_data->rd.li_cnt + 1; | |
713 | |
714 if(fbi_i | |
715 OR | |
716 ((grlc_data->rd.li[grlc_data->rd.li_cnt-1]) | |
717 AND (grlc_data->rd.m[grlc_data->rd.li_cnt-1] EQ 0))) | |
718 grlc_data->rd.data_array[bsn_i & WIN_MOD].pdu_complete = TRUE; | |
719 else | |
720 grlc_data->rd.data_array[bsn_i & WIN_MOD].pdu_complete = FALSE; | |
721 | |
722 } | |
723 | |
724 } /* rd_save_block() */ | |
725 | |
726 | |
727 | |
728 /* | |
729 +------------------------------------------------------------------------------ | |
730 | Function : rd_comp_rec_par | |
731 +------------------------------------------------------------------------------ | |
732 | Description : The function rd_comp_rec_par() .... | |
733 | | |
734 | Parameters : dummy - description of parameter dummy | |
735 | | |
736 +------------------------------------------------------------------------------ | |
737 */ | |
738 GLOBAL void rd_comp_rec_par ( UBYTE bsn_i ) | |
739 { | |
740 UBYTE vq_help; | |
741 TRACE_FUNCTION( "rd_comp_rec_par" ); | |
742 | |
743 if(grlc_data->rd.rlc_mode EQ CGRLC_RLC_MODE_ACK) | |
744 { | |
745 if( ( grlc_data->rd.vr >= grlc_data->rd.ssn) && | |
746 ( (bsn_i >= grlc_data->rd.vr ) || | |
747 (bsn_i < grlc_data->rd.ssn) ) ) | |
748 grlc_data->rd.vr = (bsn_i+1) & 0x7F; | |
749 else if( ( grlc_data->rd.vr < grlc_data->rd.ssn) && | |
750 ( (bsn_i >= grlc_data->rd.vr ) && | |
751 (bsn_i < grlc_data->rd.ssn) ) ) | |
752 grlc_data->rd.vr = (bsn_i+1) & 0x7F; | |
753 | |
754 grlc_data->rd.vn[bsn_i & WIN_MOD] = VN_RECEIVED; | |
755 vq_help = grlc_data->rd.vq; | |
756 while( (grlc_data->rd.vn[vq_help & WIN_MOD] EQ VN_RECEIVED) AND | |
757 vq_help NEQ grlc_data->rd.vr) | |
758 { | |
759 vq_help = (vq_help+1) & 0x7F; | |
760 } | |
761 grlc_data->rd.vq = vq_help; | |
762 } | |
763 else if(grlc_data->rd.rlc_mode EQ CGRLC_RLC_MODE_UACK) | |
764 { | |
765 if(grlc_data->rd.vr EQ bsn_i) | |
766 { | |
767 grlc_data->rd.vr = (1+grlc_data->rd.vr) % 128; | |
768 grlc_data->rd.vq = (1+grlc_data->rd.vq) % 128; | |
769 grlc_data->rd.inSequence = TRUE; | |
770 } | |
771 else | |
772 { | |
773 grlc_data->rd.vr = bsn_i; | |
774 grlc_data->rd.inSequence = FALSE; | |
775 } | |
776 } | |
777 else | |
778 TRACE_ERROR(" unknown RLC Mode during dl tbf in rd_comp_rec_par"); | |
779 | |
780 | |
781 | |
782 } /* rd_comp_rec_par() */ | |
783 | |
784 | |
785 | |
786 | |
787 /* | |
788 +------------------------------------------------------------------------------ | |
789 | Function : rd_check_fbi | |
790 +------------------------------------------------------------------------------ | |
791 | Description : The function rd_check_fbi() .... | |
792 | | |
793 | Parameters : dummy - description of parameter dummy | |
794 | | |
795 +------------------------------------------------------------------------------ | |
796 */ | |
797 GLOBAL UBYTE rd_check_fbi ( UBYTE fbi_i, UBYTE sp , ULONG fn , UBYTE rrbp ) | |
798 { | |
799 TRACE_FUNCTION( "rd_check_fbi" ); | |
800 | |
801 /* | |
802 * mark the bsn with fbi=1 | |
803 */ | |
804 if(fbi_i) | |
805 { | |
806 grlc_data->rd.last_bsn = grlc_data->rd.vr; | |
807 if(!sp) | |
808 { | |
809 TRACE_EVENT_P1("NO SP BUT FINAL DATA BLOCK t3192=%d",grlc_data->downlink_tbf.t3192_val); | |
810 } | |
811 } | |
812 | |
813 | |
814 /* | |
815 * if last bsn is left window element, than tbf is going to be released | |
816 */ | |
817 if(grlc_data->rd.last_bsn EQ grlc_data->rd.vq AND | |
818 !grlc_data->rd.f_ack_ind) /* to avoid retransmission */ | |
819 { | |
820 PALLOC(prim,CGRLC_T3192_STARTED_IND); | |
821 PSEND(hCommGRR,prim); | |
822 if(grlc_data->rd.rlc_mode EQ CGRLC_RLC_MODE_ACK ) | |
823 { | |
824 SET_STATE(RD,RD_REL_ACK); | |
825 } | |
826 else | |
827 { | |
828 SET_STATE(RD,RD_REL_UACK); | |
829 } | |
830 | |
831 grlc_data->tbf_ctrl[grlc_data->dl_index].fbi = 1; | |
832 | |
833 if(sp) | |
834 { | |
835 grlc_data->rd.fn_p_tbf_rel = grlc_decode_tbf_start_rel(fn,(USHORT)(rrbp+3)); | |
836 } | |
837 return 1; | |
838 } | |
839 else | |
840 { | |
841 return 0; | |
842 } | |
843 }/* rd_check_fbi() */ | |
844 | |
845 | |
846 | |
847 | |
848 /* | |
849 +------------------------------------------------------------------------------ | |
850 | Function : rd_set_acknack | |
851 +------------------------------------------------------------------------------ | |
852 | Description : The function rd_set_acknack() .... | |
853 | | |
854 | Parameters : dummy - description of parameter dummy | |
855 | | |
856 +------------------------------------------------------------------------------ | |
857 */ | |
858 GLOBAL UBYTE* rd_set_acknack ( void ) | |
859 { | |
860 MCAST (u_dl_ack,U_GRLC_DL_ACK); | |
861 UBYTE * ptr_block; | |
862 UBYTE i; | |
863 UBYTE index; | |
864 UBYTE help,neg_ack=0; | |
865 ULONG rbb1=0,rbb2=0,dummy1=0,dummy2=0; | |
866 | |
867 TRACE_FUNCTION( "rd_set_acknack" ); | |
868 | |
869 | |
870 if(grlc_data->rd.channel_req AND (grlc_data->tbf_type EQ TBF_TYPE_DL)) | |
871 { | |
872 u_dl_ack->v_chan_req_des = 1; | |
873 u_dl_ack->chan_req_des = grlc_data->chan_req_des; | |
874 grlc_data->rd.channel_req = 0; | |
875 grlc_data->rd.ch_req_in_ack_prog = TRUE; | |
876 /* TRACE_EVENT_P6("channel req des in dl ack nack:ptp=%d,rp=%d,rlc_mode=%d,llc_pt=%d,rlc_oc=%d, pst=%d", | |
877 grlc_data->chan_req_des.peak_thr_class, | |
878 grlc_data->chan_req_des.radio_prio, | |
879 grlc_data->chan_req_des.rlc_mode, | |
880 grlc_data->chan_req_des.llc_pdu_type, | |
881 grlc_data->chan_req_des.rlc_octet_cnt, | |
882 grlc_data->prim_start_tbf);*/ | |
883 if(grlc_data->prim_start_tbf >= PRIM_QUEUE_SIZE_TOTAL) | |
884 { | |
885 TRACE_EVENT_P3("PST=%d PSF=%d PDU=%d: rd_set_acknack" | |
886 ,grlc_data->prim_start_tbf | |
887 ,grlc_data->prim_start_free | |
888 ,grlc_data->grlc_data_req_cnt); | |
889 } | |
890 | |
891 } | |
892 else | |
893 { | |
894 u_dl_ack->v_chan_req_des = 0; | |
895 grlc_data->rd.channel_req = 0; | |
896 } | |
897 | |
898 u_dl_ack->msg_type = U_GRLC_DL_ACK_c; | |
899 u_dl_ack->dl_tfi = grlc_data->dl_tfi; | |
900 u_dl_ack->ack_nack_des.f_ack_ind = grlc_data->rd.f_ack_ind; | |
901 u_dl_ack->ack_nack_des.ssn = grlc_data->rd.vr; | |
902 memset(u_dl_ack->ack_nack_des.rbb, 1, WIN_SIZE ); | |
903 for(i=0; i< WIN_SIZE; i++) | |
904 { | |
905 if(grlc_data->rd.vr EQ grlc_data->rd.ssn OR grlc_data->rd.rlc_mode EQ CGRLC_RLC_MODE_UACK) | |
906 break; | |
907 index = (grlc_data->rd.vr-1-i) & 0x7F; | |
908 if(grlc_data->rd.vn[index & WIN_MOD] NEQ VN_RECEIVED) | |
909 { | |
910 u_dl_ack->ack_nack_des.rbb[WIN_SIZE-1-i] = 0; | |
911 neg_ack++; | |
912 } | |
913 if(grlc_data->rd.ssn EQ index ) | |
914 { | |
915 help = grlc_data->rd.ssn; | |
916 while(help NEQ grlc_data->rd.vq) | |
917 { | |
918 grlc_data->rd.vn[help & WIN_MOD] = VN_INVALID; | |
919 help = (help + 1) & 0x7F; | |
920 } | |
921 break; | |
922 } | |
923 } | |
924 | |
925 /* TRACE ONLY if there is channel desc or negative ack or the final ack*/ | |
926 if(u_dl_ack->v_chan_req_des OR | |
927 u_dl_ack->ack_nack_des.f_ack_ind OR | |
928 neg_ack) | |
929 { | |
930 if(neg_ack AND !u_dl_ack->ack_nack_des.f_ack_ind) | |
931 { | |
932 for(i=0; i<32;i++) | |
933 { | |
934 dummy1 = u_dl_ack->ack_nack_des.rbb[WIN_SIZE-1-i]; | |
935 dummy2 = u_dl_ack->ack_nack_des.rbb[WIN_SIZE-1-i-32]; | |
936 rbb1 += dummy1 <<i; | |
937 rbb2 += dummy2 <<i; | |
938 } | |
939 TRACE_EVENT_P7("dl_ack:p_fn=%ld,CD=%d ssn=%d nacks=%d vq=%d rbb2=%lx rbb1=%lx", | |
940 grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn, | |
941 u_dl_ack->v_chan_req_des, | |
942 u_dl_ack->ack_nack_des.ssn, | |
943 neg_ack, | |
944 grlc_data->rd.vq, | |
945 rbb2, | |
946 rbb1); | |
947 } | |
948 else | |
949 { | |
950 rbb1 = 0xFFFFFFFF; | |
951 rbb2 = 0xFFFFFFFF; | |
952 TRACE_EVENT_P6("dl_ack:p_fn=%ld,CD=%d fbi=%d ssn=%d nacks=%d vq=%d", | |
953 grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn, | |
954 u_dl_ack->v_chan_req_des, | |
955 u_dl_ack->ack_nack_des.f_ack_ind, | |
956 u_dl_ack->ack_nack_des.ssn, | |
957 neg_ack, | |
958 grlc_data->rd.vq); | |
959 } | |
960 } | |
961 else | |
962 { | |
963 rbb1 = 0xFFFFFFFF; | |
964 rbb2 = 0xFFFFFFFF; | |
965 } | |
966 | |
967 u_dl_ack->chan_qual_rep.c_value = 0; | |
968 u_dl_ack->chan_qual_rep.rxqual = 0; | |
969 u_dl_ack->chan_qual_rep.signvar = 0; | |
970 | |
971 { | |
972 /* processing channel quality report */ | |
973 | |
974 /* processing of C value */ | |
975 u_dl_ack->chan_qual_rep.c_value = meas_grlc_c_get_value( ); | |
976 | |
977 /* processing of RXQUAL value */ | |
978 u_dl_ack->chan_qual_rep.rxqual = meas_sq_get_rxqual_value( ); | |
979 | |
980 /* processing of signal variance */ | |
981 u_dl_ack->chan_qual_rep.signvar = meas_sv_get_value( ); | |
982 | |
983 /* processing of relative interference levels */ | |
984 meas_int_get_rel_i_level( &u_dl_ack->chan_qual_rep.ilev ); | |
985 } | |
986 | |
987 #if !defined (NTRACE) | |
988 | |
989 if( grlc_data->meas.v_im_trace NEQ 0 ) | |
990 { | |
991 TRACE_EVENT_P3( "rd_set_acknack: %d %d %d", | |
992 u_dl_ack->chan_qual_rep.c_value, | |
993 u_dl_ack->chan_qual_rep.rxqual, | |
994 u_dl_ack->chan_qual_rep.signvar ); | |
995 } | |
996 | |
997 #endif /* #if !defined (NTRACE) */ | |
998 | |
999 #ifdef REL99 | |
1000 | |
1001 u_dl_ack->v_release_99_str_u_grlc_dl_ack = 1; | |
1002 | |
1003 if (grlc_data->pfi_support AND u_dl_ack->v_chan_req_des ) | |
1004 { | |
1005 u_dl_ack->release_99_str_u_grlc_dl_ack.v_pfi = 1; | |
1006 u_dl_ack->release_99_str_u_grlc_dl_ack.pfi = grlc_data->pfi_value; | |
1007 } | |
1008 else | |
1009 { | |
1010 u_dl_ack->release_99_str_u_grlc_dl_ack.v_pfi = 0; | |
1011 } | |
1012 | |
1013 #endif | |
1014 | |
1015 | |
1016 grlc_data->rd.ssn = grlc_data->rd.vq; | |
1017 ptr_block = (_decodedMsg); | |
1018 | |
1019 | |
1020 return ptr_block; | |
1021 } /* rd_set_acknack() */ | |
1022 | |
1023 | |
1024 /* | |
1025 +------------------------------------------------------------------------------ | |
1026 | Function : rd_calc_rlc_data_len | |
1027 +------------------------------------------------------------------------------ | |
1028 | Description : The function rd_calc_rlc_data_len() calculates the Data size of | |
1029 | an RLC data block depending on coding scheme. | |
1030 | The size is described in bytes. | |
1031 | | |
1032 | Parameters : block_status_i - includes the Coding scheme which | |
1033 | determines the size of an RLC data block | |
1034 | | |
1035 +------------------------------------------------------------------------------ | |
1036 */ | |
1037 GLOBAL UBYTE rd_calc_rlc_data_len ( USHORT block_status_i ) | |
1038 { | |
1039 UBYTE result=0; | |
1040 TRACE_FUNCTION( "rd_calc_rlc_data_len" ); | |
1041 | |
1042 /* | |
1043 * the coding scheme is only in the first four bits | |
1044 */ | |
1045 block_status_i = block_status_i & 0x000F; | |
1046 | |
1047 switch( block_status_i) | |
1048 { | |
1049 case 2: | |
1050 grlc_data->rd.cs_type = CS_1; | |
1051 break; | |
1052 case 4: | |
1053 grlc_data->rd.cs_type = CS_2; | |
1054 break; | |
1055 case 5: | |
1056 grlc_data->rd.cs_type = CS_3; | |
1057 break; | |
1058 case 6: | |
1059 grlc_data->rd.cs_type = CS_4; | |
1060 break; | |
1061 default: | |
1062 TRACE_EVENT("No Coding Scheme in RLC data block defined, old CS is used"); | |
1063 break; | |
1064 } | |
1065 | |
1066 | |
1067 switch( grlc_data->rd.cs_type) | |
1068 { | |
1069 /* | |
1070 * NO CS defined in all previously received RLC data blocks, | |
1071 * therefore default CS_1 is used | |
1072 */ | |
1073 case CS_ZERO: | |
1074 case CS_1: | |
1075 result = 20; | |
1076 break; | |
1077 case CS_2: | |
1078 result = 30; | |
1079 break; | |
1080 case CS_3: | |
1081 result = 36; | |
1082 break; | |
1083 case CS_4: | |
1084 result = 50; | |
1085 break; | |
1086 default: | |
1087 TRACE_ERROR("unknown Coding Scheme"); | |
1088 break; | |
1089 } | |
1090 | |
1091 return result; | |
1092 } /* rd_calc_rlc_data_len() */ | |
1093 | |
1094 | |
1095 | |
1096 /* | |
1097 +------------------------------------------------------------------------------ | |
1098 | Function : rd_fill_blocks | |
1099 +------------------------------------------------------------------------------ | |
1100 | Description : The function rd_fill_blocks() fills not received but needed | |
1101 | RLC data blocks with the value Zero. | |
1102 | | |
1103 | Parameters : bsn_i - bsn value of the recently received RLC data block, | |
1104 | which is not inSequence(not equal VR at receiving the block) | |
1105 | | |
1106 +------------------------------------------------------------------------------ | |
1107 */ | |
1108 GLOBAL void rd_fill_blocks ( UBYTE bsn_i ) | |
1109 { | |
1110 T_NEXT_ARRAY * ptr_temp=NULL; | |
1111 TRACE_FUNCTION( "rd_fill_blocks" ); | |
1112 | |
1113 do | |
1114 { | |
1115 MALLOC(ptr_temp, sizeof(T_NEXT_ARRAY)); | |
1116 ptr_temp->next = NULL; | |
1117 ptr_temp->len = grlc_data->rd.rlc_data_len; | |
1118 memset(ptr_temp->data,0,ptr_temp->len); | |
1119 grlc_data->rd.data_array[grlc_data->rd.vq & WIN_MOD].first = ptr_temp; | |
1120 grlc_data->rd.data_array[grlc_data->rd.vq & WIN_MOD].pdu_cnt = 0; | |
1121 grlc_data->rd.data_array[grlc_data->rd.vq & WIN_MOD].pdu_complete =FALSE; | |
1122 rd_send_grlc_data_ind(grlc_data->rd.vq); | |
1123 grlc_data->rd.vq = (1+grlc_data->rd.vq) % 128; /*modulo 128*/ | |
1124 } | |
1125 while(grlc_data->rd.vq NEQ bsn_i); | |
1126 | |
1127 grlc_data->rd.vq = (1+grlc_data->rd.vq) % 128; /*modulo 128*/ | |
1128 grlc_data->rd.vr = grlc_data->rd.vq; | |
1129 grlc_data->rd.inSequence = TRUE; | |
1130 | |
1131 | |
1132 | |
1133 } /* rd_fill_blocks() */ | |
1134 | |
1135 | |
1136 | |
1137 | |
1138 /* | |
1139 +------------------------------------------------------------------------------ | |
1140 | Function : rd_calc_delta_fn | |
1141 +------------------------------------------------------------------------------ | |
1142 | Description : The function rd_calc_delta_fn() calculates delta_fn. It is | |
1143 | needed at receiving mac_ready_ind to send a poll block. | |
1144 | In Target Enviroment, the poll block(Ack/nack or Control block) | |
1145 | must be calculated one radio block earlier then the send time. | |
1146 | This is needed due to the functional interface. | |
1147 | Parameters : fn_i - framenumber for the uplink call | |
1148 | | |
1149 | | |
1150 +------------------------------------------------------------------------------ | |
1151 */ | |
1152 GLOBAL ULONG rd_calc_delta_fn ( ULONG fn_i ) | |
1153 { | |
1154 ULONG result; | |
1155 TRACE_FUNCTION( "rd_calc_delta_fn" ); | |
1156 | |
1157 #ifdef _TARGET_ | |
1158 { | |
1159 if(fn_i EQ FN_MAX-5) | |
1160 result = grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn + 5; | |
1161 else | |
1162 result = grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn - fn_i; | |
1163 } | |
1164 #endif | |
1165 | |
1166 #ifdef _SIMULATION_ | |
1167 { | |
1168 if(fn_i EQ grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn) | |
1169 result = 4; /*valid: send block*/ | |
1170 else | |
1171 result = 0; /*no poll sending*/ | |
1172 } | |
1173 #endif | |
1174 | |
1175 return result; | |
1176 | |
1177 | |
1178 } /* rd_calc_delta_fn() */ | |
1179 | |
1180 /* | |
1181 +------------------------------------------------------------------------------ | |
1182 | Function : rd_free_desc_list_partions | |
1183 +------------------------------------------------------------------------------ | |
1184 | Description : The function rd_free_desc_list_partions() frees the partions, | |
1185 | which are linked for a candidate LLC pdu. PDU is stored as a | |
1186 | description list, but not passed to LLC because of incomplete. | |
1187 | Parameters : | |
1188 | | |
1189 +------------------------------------------------------------------------------ | |
1190 */ | |
1191 GLOBAL void rd_free_desc_list_partions ( void ) | |
1192 { | |
1193 UBYTE cnt = 0; | |
1194 T_NEXT_ARRAY *help = NULL; | |
1195 | |
1196 TRACE_FUNCTION( "rd_free_desc_list_partions" ); | |
1197 | |
1198 help = (T_NEXT_ARRAY*)grlc_data->rd.grlc_data_ind.desc_list.first; | |
1199 | |
1200 grlc_data->rd.grlc_data_ind.desc_list.first = NULL; | |
1201 | |
1202 while(help != NULL) | |
1203 { | |
1204 T_NEXT_ARRAY *ptr = (T_NEXT_ARRAY*) help->next; | |
1205 MFREE(help); | |
1206 help = ptr; | |
1207 cnt++; | |
1208 } | |
1209 | |
1210 | |
1211 #ifdef _SIMULATION_ | |
1212 TRACE_EVENT_P1("freed partion (linked) : cnt=%d",cnt); | |
1213 #endif /* _SIMULATION_*/ | |
1214 | |
1215 | |
1216 grlc_data->rd.pdu_complete = TRUE; | |
1217 grlc_data->rd.pdu_len = 0; | |
1218 | |
1219 | |
1220 } /* rd_free_desc_list_partions() */ | |
1221 | |
1222 /* | |
1223 +------------------------------------------------------------------------------ | |
1224 | Function : rd_free_database_partions | |
1225 +------------------------------------------------------------------------------ | |
1226 | Description : The function rd_free_database_partions() frees the partions, | |
1227 | which are stored in the RD database. They are not linked to a | |
1228 | LLC pdu because data blocks are not received in sequence. | |
1229 | Partions are removed from left window size (vq) up to the | |
1230 | right window size (vr). | |
1231 | Parameters : | |
1232 | | |
1233 +------------------------------------------------------------------------------ | |
1234 */ | |
1235 GLOBAL void rd_free_database_partions ( void ) | |
1236 { | |
1237 USHORT bsn; | |
1238 | |
1239 UBYTE cnt=0; | |
1240 | |
1241 T_NEXT_ARRAY *help = NULL; | |
1242 | |
1243 TRACE_FUNCTION( "rd_free_database_partions" ); | |
1244 | |
1245 bsn = grlc_data->rd.vq; | |
1246 | |
1247 while (bsn NEQ grlc_data->rd.vr) | |
1248 { | |
1249 help = grlc_data->rd.data_array[bsn & WIN_MOD].first; | |
1250 #ifdef _SIMULATION_ | |
1251 TRACE_EVENT_P2("candiate bsn=%d vn=%d",bsn,grlc_data->rd.vn[bsn & WIN_MOD]); | |
1252 #endif /* _SIMULATION_*/ | |
1253 | |
1254 while (help != NULL) | |
1255 { | |
1256 grlc_data->rd.data_array[bsn & WIN_MOD].first = | |
1257 (T_NEXT_ARRAY *)grlc_data->rd.data_array[bsn & WIN_MOD].first->next; | |
1258 | |
1259 MFREE(help); | |
1260 | |
1261 cnt++; | |
1262 #ifdef _SIMULATION_ | |
1263 TRACE_EVENT_P1("element free : bsn=%d",bsn); | |
1264 #endif /* _SIMULATION_*/ | |
1265 if(grlc_data->rd.data_array[bsn & WIN_MOD].pdu_cnt) | |
1266 help = grlc_data->rd.data_array[bsn & WIN_MOD].first; | |
1267 else | |
1268 help = NULL; | |
1269 } | |
1270 grlc_data->rd.data_array[bsn & WIN_MOD].pdu_complete = FALSE; | |
1271 grlc_data->rd.data_array[bsn & WIN_MOD].pdu_cnt = 0xFF; | |
1272 grlc_data->rd.data_array[bsn & WIN_MOD].first = NULL; | |
1273 | |
1274 bsn = (bsn + 1) & 0x7F; | |
1275 } | |
1276 TRACE_EVENT_P2("rd_free_database_partions after: bsn=%d cnt=%d ", bsn, cnt); | |
1277 | |
1278 | |
1279 } /* rd_free_database_partions() */ | |
1280 | |
1281 | |
1282 /* | |
1283 +------------------------------------------------------------------------------ | |
1284 | Function : rd_cgrlc_st_time_ind | |
1285 +------------------------------------------------------------------------------ | |
1286 | Description : The function rd_cgrlc_st_time_ind () informs higher layers | |
1287 | that the starting time is elapsed | |
1288 | | |
1289 | Parameters : - | |
1290 | | |
1291 +------------------------------------------------------------------------------ | |
1292 */ | |
1293 GLOBAL void rd_cgrlc_st_time_ind ( void ) | |
1294 { | |
1295 PALLOC(cgrlc_starting_time_ind,CGRLC_STARTING_TIME_IND); /* T_CGRLC_STARTING_TIME_IND */ | |
1296 | |
1297 TRACE_FUNCTION( "rd_cgrlc_st_time_ind " ); | |
1298 | |
1299 cgrlc_starting_time_ind->tbf_mode = CGRLC_TBF_MODE_DL; | |
1300 cgrlc_starting_time_ind->tfi = grlc_data->dl_tfi; | |
1301 | |
1302 PSEND(hCommGRR,cgrlc_starting_time_ind); | |
1303 | |
1304 grlc_data->dl_tn_mask = grlc_data->downlink_tbf.ts_mask; | |
1305 | |
1306 | |
1307 } /* rd_cgrlc_st_time_ind () */ |