comparison src/g23m-gprs/grlc/grlc_f.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 global functions for GRLC
18 +-----------------------------------------------------------------------------
19 */
20
21 #ifndef GRLC_F_C
22 #define GRLC_F_C
23 #endif
24
25 #define ENTITY_GRLC
26
27
28 /*==== INCLUDES =============================================================*/
29
30 #include <stdio.h>
31 #include <string.h> /* to get definition of memcpy() */
32 #include <math.h>
33
34 #include "typedefs.h" /* to get Condat data types */
35 #include "vsi.h" /* to get a lot of macros */
36 #include "macdef.h"
37 #include "gprs.h"
38 #include "gsm.h" /* to get a lot of macros */
39 #include "ccdapi.h" /* to get CCD API */
40 #include "cnf_grlc.h" /* to get cnf-definitions */
41 #include "mon_grlc.h" /* to get mon-definitions */
42 #include "prim.h" /* to get the definitions of used SAP and directions */
43 #include "message.h" /* to get message describtion */
44 #include "pcm.h"
45
46 #include "grlc.h" /* to get the global entity definitions */
47
48 #include "grlc_f.h" /* to check own definitions */
49 #include "grlc_tmf.h" /* to get definition of tm_grlc_init() */
50 #include "grlc_gfff.h" /* to get definition of gff_init() */
51 #include "grlc_rdf.h" /* to get definition of rd_init() */
52 #include "grlc_ruf.h" /* to get definition of ru_init() */
53 #include "grlc_rus.h"
54 #include "grlc_rds.h"
55 #include "grlc_tms.h"
56 #include "grlc_tpcs.h"
57 #include "grlc_meass.h"
58 #include "cl_rlcmac.h"
59
60 /*==== CONST ================================================================*/
61
62 /*==== DIAGNOSTICS ==========================================================*/
63
64 /*==== LOCAL VARS ===========================================================*/
65
66 /*==== GLOBAL VARS ===========================================================*/
67 /*==== LOCAL MACROS =========================================================*/
68
69
70 /*==== FUNCTIONS PROTOTYPES =================================================*/
71
72 LOCAL void grlc_encode_dl_acknack ( UBYTE * ptr_out );
73
74 LOCAL void grlc_encode_ul_dummy ( UBYTE * ptr_out );
75
76 LOCAL void grlc_encode_pca ( UBYTE * ptr_out );
77
78 LOCAL UBYTE grlc_decode_ul_acknack ( UBYTE * ptr_blk );
79
80 LOCAL UBYTE grlc_ccd_error_handling ( UBYTE entity_i );
81
82 LOCAL USHORT grlc_convert_11bit_2_etsi ( USHORT eleven_bit );
83
84 /*==== FUNCTIONS ============================================================*/
85 /*
86 +------------------------------------------------------------------------------
87 | Function : grlc_encode_dl_acknack
88 +------------------------------------------------------------------------------
89 | Description : The function grlc_encode_dl_acknack() encodes the packet downlink
90 | ack/nack block without CCD
91 |
92 | Parameters : *ptr_out_i- ptr to the buffer where the air message will be placed
93 |
94 |
95 +------------------------------------------------------------------------------
96 */
97 LOCAL void grlc_encode_dl_acknack ( UBYTE * ptr_out)
98 {
99 MCAST (u_dl_ack,U_GRLC_DL_ACK); /* T_U_GRLC_DL_ACK */
100
101 UBYTE i=0, bit=0,byte,bit_in_byte,j;
102
103 TRACE_FUNCTION( "grlc_encode_dl_acknack" );
104
105 /******************* mandatory elements ****************************/
106
107 /* MESSAGE TYPE 6 bit */
108 ptr_out[0] = u_dl_ack->msg_type << 2;
109 bit +=6;
110 /* DL TFI 5 bit */
111 ptr_out[0] |= (u_dl_ack->dl_tfi >> 3) & 0x03;
112 ptr_out[1] = (u_dl_ack->dl_tfi << 5);
113 bit +=5;
114 /* ACK NACK DESCRIPTION */
115 /* final ack indication 1 bit */
116 ptr_out[1] |= (u_dl_ack->ack_nack_des.f_ack_ind << 4);
117 bit +=1;
118 /* ssn 7 bit */
119 ptr_out[1] |= (u_dl_ack->ack_nack_des.ssn >> 3);
120 ptr_out[2] = (u_dl_ack->ack_nack_des.ssn << 5);
121 bit +=7;
122 for (i=0;i<64; i++)
123 {
124 byte = bit / 8; /* byte pos */
125 bit_in_byte = bit % 8; /* rel bit pos in the current byte */
126 ptr_out[byte] |= u_dl_ack->ack_nack_des.rbb[i] << (7-bit_in_byte);
127 bit +=1;
128 }
129 /* CHANNEL REQUEST DESCRIPTION */
130 /* valid flag*/
131 byte = bit / 8;
132 bit_in_byte = bit % 8;
133 ptr_out[byte] |= u_dl_ack->v_chan_req_des << (7-bit_in_byte);
134 bit +=1;
135 if(u_dl_ack->v_chan_req_des)
136 {
137 /* peak_thr_class */
138 for(i=0;i<4;i++)
139 {
140 byte = bit / 8;
141 bit_in_byte = bit % 8;
142 ptr_out[byte] |= (u_dl_ack->chan_req_des.peak_thr_class >> (3-i)) << (7-bit_in_byte);
143 bit +=1;
144 }
145 /* radio prio */
146 for(i=0;i<2;i++)
147 {
148 byte = bit / 8;
149 bit_in_byte = bit % 8;
150 ptr_out[byte] |= (u_dl_ack->chan_req_des.radio_prio >> (1-i)) << (7-bit_in_byte);
151 bit +=1;
152 }
153 /* rlc_mode*/
154 byte = bit / 8;
155 bit_in_byte = bit % 8;
156 ptr_out[byte] |= (u_dl_ack->chan_req_des.rlc_mode) << (7-bit_in_byte);
157 bit +=1;
158 /* llc pdu type*/
159 byte = bit / 8;
160 bit_in_byte = bit % 8;
161 ptr_out[byte] |= (u_dl_ack->chan_req_des.llc_pdu_type) << (7-bit_in_byte);
162 bit +=1;
163 /* rlc_oct_cnt */
164 for(i=0;i<16;i++)
165 {
166 byte = bit / 8;
167 bit_in_byte = bit % 8;
168 ptr_out[byte] |= (u_dl_ack->chan_req_des.rlc_octet_cnt >> (15-i)) << (7-bit_in_byte);
169 bit +=1;
170 }
171 }
172 /* CHANNEL QUALITY REPORT */
173 /* c_value */
174 for(i=0;i<6;i++)
175 {
176 byte = bit / 8;
177 bit_in_byte = bit % 8;
178 ptr_out[byte] |= (u_dl_ack->chan_qual_rep.c_value >> (5-i)) << (7-bit_in_byte);
179 bit +=1;
180 }
181 /* rxqual */
182 for(i=0;i<3;i++)
183 {
184 byte = bit / 8;
185 bit_in_byte = bit % 8;
186 ptr_out[byte] |= (u_dl_ack->chan_qual_rep.rxqual >> (2-i)) << (7-bit_in_byte);
187 bit +=1;
188 }
189 /* signvar */
190 for(i=0;i<6;i++)
191 {
192 byte = bit / 8;
193 bit_in_byte = bit % 8;
194 ptr_out[byte] |= (u_dl_ack->chan_qual_rep.signvar >> (5-i)) << (7-bit_in_byte);
195 bit +=1;
196 }
197 /* c_value */
198 for(j=0;j<8;j++)
199 {
200 UBYTE flag,value;
201
202 switch(j)
203 {
204 case 0:
205 flag = u_dl_ack->chan_qual_rep.ilev.v_ilev0;
206 value = u_dl_ack->chan_qual_rep.ilev.ilev0;
207 break;
208 case 1:
209 flag = u_dl_ack->chan_qual_rep.ilev.v_ilev1;
210 value = u_dl_ack->chan_qual_rep.ilev.ilev1;
211 break;
212 case 2:
213 flag = u_dl_ack->chan_qual_rep.ilev.v_ilev2;
214 value = u_dl_ack->chan_qual_rep.ilev.ilev2;
215 break;
216 case 3:
217 flag = u_dl_ack->chan_qual_rep.ilev.v_ilev3;
218 value = u_dl_ack->chan_qual_rep.ilev.ilev3;
219 break;
220 case 4:
221 flag = u_dl_ack->chan_qual_rep.ilev.v_ilev4;
222 value = u_dl_ack->chan_qual_rep.ilev.ilev4;
223 break;
224 case 5:
225 flag = u_dl_ack->chan_qual_rep.ilev.v_ilev5;
226 value = u_dl_ack->chan_qual_rep.ilev.ilev5;
227 break;
228 case 6:
229 flag = u_dl_ack->chan_qual_rep.ilev.v_ilev6;
230 value = u_dl_ack->chan_qual_rep.ilev.ilev6;
231 break;
232 case 7:
233 flag = u_dl_ack->chan_qual_rep.ilev.v_ilev7;
234 value = u_dl_ack->chan_qual_rep.ilev.ilev7;
235 break;
236 default:
237 TRACE_EVENT_P1("no valid j=%d value during grlc_encode_dl_acknack should not appear ",j);
238 flag = 0;
239 value = 0;
240 break;
241 }
242 byte = bit / 8;
243 bit_in_byte = bit % 8;
244 ptr_out[byte] |= (flag) << (7-bit_in_byte);
245 bit +=1;
246 if(flag)
247 {
248 for(i=0;i<4;i++)
249 {
250 byte = bit / 8;
251 bit_in_byte = bit % 8;
252 ptr_out[byte] |= (value >> (3-i)) << (7-bit_in_byte);
253 bit +=1;
254 }
255 }
256 }
257
258 /* RELEASE 99*/
259 #ifdef REL99
260 byte = bit / 8;
261 bit_in_byte = bit % 8;
262 ptr_out[byte] |= u_dl_ack->v_release_99_str_u_grlc_dl_ack << (7-bit_in_byte);
263 bit +=1;
264
265 if(u_dl_ack->v_release_99_str_u_grlc_dl_ack)
266 {
267 byte = bit / 8;
268 bit_in_byte = bit % 8;
269
270 if(u_dl_ack->release_99_str_u_grlc_dl_ack.v_pfi)
271 {
272 ptr_out[byte] |= u_dl_ack->release_99_str_u_grlc_dl_ack.v_pfi << (7-bit_in_byte);
273 bit +=1;
274 for(i=0;i<6;i++)
275 {
276 byte = bit / 8;
277 bit_in_byte = bit % 8;
278 ptr_out[byte] |= (u_dl_ack->release_99_str_u_grlc_dl_ack.pfi >> (6-i)) << (7-bit_in_byte);
279 bit +=1;
280 }
281
282 }
283 else
284 {
285 ptr_out[byte] |= u_dl_ack->release_99_str_u_grlc_dl_ack.v_pfi << (7-bit_in_byte);
286 bit +=1;
287 }
288 }
289
290 bit++;
291 #endif
292
293 /* SPARE PADDINGS */
294 byte = bit / 8;
295 bit_in_byte = bit % 8;
296
297 if(bit_in_byte < 7)
298 {
299 UBYTE mask;
300
301 mask= 0xff >> (bit_in_byte);
302 mask &= 0x2B;
303 ptr_out[byte] |= mask;
304 }
305 for(i=byte;i<22;i++)
306 {
307 byte++;
308 ptr_out[byte] = 0x2B;
309
310 }
311 } /* grlc_encode_dl_acknack() */
312
313 /*
314 +------------------------------------------------------------------------------
315 | Function : grlc_encode_ul_dummy
316 +------------------------------------------------------------------------------
317 | Description : The function grlc_encode_ul_dummy() encodes the packet uplink
318 | dummy block without CCD
319 |
320 | Parameters : *ptr_out_i- ptr to the buffer where the air message will be placed
321 |
322 |
323 +------------------------------------------------------------------------------
324 */
325 LOCAL void grlc_encode_ul_dummy ( UBYTE * ptr_out)
326 {
327 MCAST (ul_dummy,U_GRLC_UL_DUMMY); /* T_U_GRLC_UL_DUMMY */
328
329 UBYTE i;
330
331 TRACE_FUNCTION( "grlc_encode_ul_dummy" );
332
333 /******************* mandatory elements ****************************/
334
335 ptr_out[0] = ul_dummy->msg_type << 2;
336 ptr_out[0] |= (UBYTE) (grlc_data->uplink_tbf.tlli >> 30); /* 1100 0000 0000 0000 0000 0000 0000 0000 */
337 ptr_out[1] = (UBYTE) ((grlc_data->uplink_tbf.tlli & 0x3FC00000) >> 22); /* 0011 1111 1100 0000 0000 0000 0000 0000 */
338 ptr_out[2] = (UBYTE) ((grlc_data->uplink_tbf.tlli & 0x003FC000) >> 14); /* 0000 0000 0011 1111 1100 0000 0000 0000 */
339 ptr_out[3] = (UBYTE) ((grlc_data->uplink_tbf.tlli & 0x00003FC0) >> 6); /* 0000 0000 0000 0000 0011 1111 1100 0000 */
340 ptr_out[4] = (UBYTE) ((grlc_data->uplink_tbf.tlli & 0x0000003F) << 2); /* 0000 0000 0000 0000 0000 0000 0011 1111 */
341 ptr_out[4] |= 0x01; /* spare paddings */
342
343 for(i=5;i<22;i++)
344 ptr_out[i] = 0x2B;
345 } /* grlc_encode_ul_dummy() */
346
347 /*
348 +------------------------------------------------------------------------------
349 | Function : grlc_encode_pca
350 +------------------------------------------------------------------------------
351 | Description : The function grlc_encode_pca() encodes the packet control
352 | acknowledgement block without CCD
353 |
354 | Parameters : *ptr_out_i- ptr to the buffer where the air message will be placed
355 |
356 |
357 +------------------------------------------------------------------------------
358 */
359 LOCAL void grlc_encode_pca ( UBYTE * ptr_out)
360 {
361 MCAST(u_ctrl_ack,U_GRLC_CTRL_ACK); /* T_U_GRLC_CTRL_ACK */
362
363 UBYTE i;
364
365 TRACE_FUNCTION( "grlc_encode_pca" );
366
367 /******************* mandatory elements ****************************/
368
369 ptr_out[0] = u_ctrl_ack->msg_type << 2;
370 ptr_out[0] |= (UBYTE) (grlc_data->uplink_tbf.tlli >> 30); /* 1100 0000 0000 0000 0000 0000 0000 0000 */
371 ptr_out[1] = (UBYTE) ((grlc_data->uplink_tbf.tlli & 0x3FC00000) >> 22); /* 0011 1111 1100 0000 0000 0000 0000 0000 */
372 ptr_out[2] = (UBYTE) ((grlc_data->uplink_tbf.tlli & 0x003FC000) >> 14); /* 0000 0000 0011 1111 1100 0000 0000 0000 */
373 ptr_out[3] = (UBYTE) ((grlc_data->uplink_tbf.tlli & 0x00003FC0) >> 6); /* 0000 0000 0000 0000 0011 1111 1100 0000 */
374 ptr_out[4] = (UBYTE) ((grlc_data->uplink_tbf.tlli & 0x0000003F) << 2); /* 0000 0000 0000 0000 0000 0000 0011 1111 */
375 ptr_out[4] |= u_ctrl_ack->pctrl_ack & 0x03;
376
377 for(i=5;i<22;i++)
378 ptr_out[i] = 0x2B;
379 } /* grlc_encode_pca() */
380 /*
381 +------------------------------------------------------------------------------
382 | Function : grlc_decode_ul_acknack
383 +------------------------------------------------------------------------------
384 | Description : The function grlc_decode_ul_acknack() decodes the packet uplink
385 | ack/nack without CCD
386 |
387 | Parameters : *ptr_blk- ptr to the air message
388 |
389 | Return value: returns decode status of air message:ccdOK,ccdWarning,ccdError
390 |
391 +------------------------------------------------------------------------------
392 */
393 LOCAL UBYTE grlc_decode_ul_acknack ( UBYTE *ptr_blk )
394 {
395 MCAST(d_ul_ack,D_GRLC_UL_ACK);/* T_D_GRLC_UL_ACK */
396
397 UBYTE i,j,k;
398 UBYTE bit_pos;
399 #ifdef REL99
400 UBYTE flag;
401 #endif
402
403 UBYTE result =ccdOK;
404
405 TRACE_FUNCTION( "grlc_decode_ul_acknack" );
406
407 /******************* mandatory elements ****************************/
408
409 d_ul_ack->msg_type = (ptr_blk[0] & 0xFC) >> 2 ;
410 d_ul_ack->page_mode = ptr_blk[0] & 0x03;
411
412 if((ptr_blk[1] & 0xC0)) /* distrubiton part error check */
413 {
414 TRACE_ERROR("P UL ACK: DISTRUBITION PART ERROR");
415 TRACE_EVENT_P2("P UL ACK: DISTRUBITION PART ERROR byte = 0x2%x res = 0x%2x",ptr_blk[1] ,ptr_blk[1] & 0xC0);
416 return ccdError;
417 }
418 d_ul_ack->ul_tfi = (ptr_blk[1] & 0x3E) >> 1;
419
420 if((ptr_blk[1] & 0x01)) /* message escape bit check */
421 {
422 #ifdef REL99
423 d_ul_ack->egprs_flag = TRUE;
424 #endif
425 TRACE_ERROR("P UL ACK: MESSAGE ESCAPE ERROR");
426 TRACE_EVENT_P2("P UL ACK: MESSAGE ESCAPE ERROR byte = 0x2%x res = 0x%2x",ptr_blk[1] ,ptr_blk[1] & 0x01);
427 return ccdError;
428 }
429
430 d_ul_ack->v_gprs_ul_ack_nack_info = TRUE;
431
432 d_ul_ack->gprs_ul_ack_nack_info.chan_coding_cmd = (ptr_blk[2] & 0xC0) >> 6;
433
434 #ifdef _SIMULATION_
435 TRACE_EVENT_P2("tfi=%d ch_c_cmd=%d",d_ul_ack->ul_tfi,d_ul_ack->gprs_ul_ack_nack_info.chan_coding_cmd);
436 #endif /* _SIMULATION_ */
437 /******************* Ack/Nack description ****************************/
438 d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.f_ack_ind = (ptr_blk[2] & 0x20) >> 5;
439 d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.ssn = (ptr_blk[2] << 2) & 0x7C;
440 d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.ssn |= (ptr_blk[3] >> 6) & 0x03;
441
442 j= 3; /* inital byte of rbb field */
443 k= 2; /* inital bit of rbb field */
444
445 for(i=0; i< 64;i++)
446 {
447 d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.rbb[i] = (ptr_blk[j] & (0x80>>k)) >> (7-k);
448 k++;
449 if(k EQ 8)
450 {
451 k=0;
452 j++;
453 }
454 }
455 #ifdef _SIMULATION_
456 TRACE_EVENT_P2("fai=%d ssn=%d",d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.f_ack_ind,d_ul_ack->gprs_ul_ack_nack_info.ack_nack_des.ssn);
457 #endif /* _SIMULATION_ */
458
459 bit_pos = 91; /* abs bit position */
460
461 /******************* contention resolution tlli ***********************/
462
463 j = bit_pos / 8; /* byte pos */
464 k = bit_pos % 8; /* rel bit pos */
465
466 d_ul_ack->gprs_ul_ack_nack_info.v_cr_tlli = (ptr_blk[j] >> (8-k)) & 0x01;
467
468 bit_pos++;
469
470 if(d_ul_ack->gprs_ul_ack_nack_info.v_cr_tlli)
471 {
472 d_ul_ack->gprs_ul_ack_nack_info.cr_tlli.l_cr_tlli = 32;
473 d_ul_ack->gprs_ul_ack_nack_info.cr_tlli.o_cr_tlli = 3;
474 d_ul_ack->gprs_ul_ack_nack_info.cr_tlli.b_cr_tlli[0] = ptr_blk[j];
475 d_ul_ack->gprs_ul_ack_nack_info.cr_tlli.b_cr_tlli[1] = ptr_blk[j+1];
476 d_ul_ack->gprs_ul_ack_nack_info.cr_tlli.b_cr_tlli[2] = ptr_blk[j+2];
477 d_ul_ack->gprs_ul_ack_nack_info.cr_tlli.b_cr_tlli[3] = ptr_blk[j+3];
478 d_ul_ack->gprs_ul_ack_nack_info.cr_tlli.b_cr_tlli[4] = ptr_blk[j+4];
479 bit_pos+=32;
480 }
481
482 #ifdef REL99
483 /******************* packet timing advance ****************************/
484 j = bit_pos / 8; /* byte pos */
485 k = bit_pos % 8; /* rel bit pos */
486 flag = (ptr_blk[j] >> (8-k)) & 0x01;
487 bit_pos++;
488 if(flag)
489 {
490 }
491 /******************* power control params ****************************/
492 j = bit_pos / 8; /* byte pos */
493 k = bit_pos % 8; /* rel bit pos */
494 flag = (ptr_blk[j] >> (8-k)) & 0x01;
495 bit_pos++;
496 if(flag)
497 {
498 }
499 /******************* Extension bits ****************************/
500 j = bit_pos / 8; /* byte pos */
501 k = bit_pos % 8; /* rel bit pos */
502 flag = (ptr_blk[j] >> (8-k)) & 0x01;
503 bit_pos++;
504 if(flag)
505 {
506 }
507 /******************* Fixed Alloc ****************************/
508 j = bit_pos / 8; /* byte pos */
509 k = bit_pos % 8; /* rel bit pos */
510 flag = (ptr_blk[j] >> (8-k)) & 0x01;
511 bit_pos++;
512 if(flag)
513 {
514 }
515 /******************* R99 FLAG ****************************/
516 j = bit_pos / 8; /* byte pos */
517 k = bit_pos % 8; /* rel bit pos */
518 bit_pos++;
519 d_ul_ack->gprs_ul_ack_nack_info.v_release_99_str_d_ul_ack = (ptr_blk[j] >> (8-k)) & 0x01;
520 /******************* Extended PTA ****************************/
521 j = bit_pos / 8; /* byte pos */
522 k = bit_pos % 8; /* rel bit pos */
523 flag = (ptr_blk[j] >> (8-k)) & 0x01;
524 bit_pos++;
525 if(flag)
526 {
527 }
528 /**********************************************************************/
529 j = bit_pos / 8; /* byte pos */
530 k = bit_pos % 8; /* rel bit pos */
531 d_ul_ack->gprs_ul_ack_nack_info.release_99_str_d_ul_ack.tbf_est = (ptr_blk[j] >> (8-k)) & 0x01;
532
533 #endif
534
535 return(result);
536
537 } /* grlc_decode_ul_acknack() */
538
539 /*
540 +------------------------------------------------------------------------------
541 | Function : grlc_ccd_error_handling
542 +------------------------------------------------------------------------------
543 | Description : The function grlc_ccd_error_handling() ...
544 |
545 | Parameters : entity_i - the CCD was called for this entity
546 |
547 +------------------------------------------------------------------------------
548 */
549 LOCAL UBYTE grlc_ccd_error_handling ( UBYTE entity_i )
550 {
551 UBYTE result = DELETE_MESSAGE;
552 USHORT parlist [MAX_ERR_PAR];
553 UBYTE first_error;
554
555 TRACE_FUNCTION( "grlc_ccd_error_handling" );
556
557
558 memset (parlist, 0, sizeof (parlist));
559
560 first_error = ccd_getFirstError (entity_i, parlist);
561
562 switch (first_error)
563 {
564
565 case ERR_PATTERN_MISMATCH: /* A spare pattern does not match with */
566 /* the specified content */
567 /* Error params[0] = bitposition */
568 {
569 MCAST(ptr,D_GRLC_UL_ACK);
570 result = ptr->msg_type;
571 }
572 break;
573
574 default:
575 /* SZML-GLBL/010 */
576 TRACE_ERROR( "Ctrl-Message will be deleted" );
577 break;
578 }
579
580 return(result);
581
582 } /* grlc_ccd_error_handling() */
583
584
585 /*==== PUBLIC FUNCTIONS =====================================================*/
586
587
588 /*
589 +------------------------------------------------------------------------------
590 | Function : grlc_buffer2ulong
591 +------------------------------------------------------------------------------
592 | Description : The function grlc_buffer2ulong() copy a 32-Bit-Buffer in a ULONG
593 | variable
594 |
595 | SZML-GLBL/002
596 |
597 | Parameters : ptmsi - pointer to buffer that contains the 32bit for the ULONG
598 |
599 +------------------------------------------------------------------------------
600 */
601 GLOBAL ULONG grlc_buffer2ulong ( BUF_cr_tlli *tlli)
602 {
603 ULONG ul;
604
605 UBYTE l, dummy;
606 USHORT i, ii;
607 UBYTE off1, off2;
608
609 TRACE_FUNCTION( "grlc_buffer2ulong ");
610
611 ul= 0;
612
613 l = (UBYTE)tlli->l_cr_tlli;
614
615 off1 = tlli->o_cr_tlli / 8;
616 off2 = tlli->o_cr_tlli % 8;
617
618 dummy = 0;
619 dummy = tlli->b_cr_tlli[off1] << off2;
620
621 if(l <= (8-off2))
622 {
623 dummy = dummy >> (8-l);
624 ul |= dummy;
625 return ul;
626 }
627 dummy = dummy >> off2;
628 ul |= dummy;
629 l -= (8-off2);
630
631 do
632 {
633 off1++;
634
635 if(l < 8)
636 {
637 dummy = tlli->b_cr_tlli[off1] >> (8-l);
638 ii = 1;
639 ul = ul << l;
640 for(i=0; i< l; i++)
641 {
642 ul = ul | (dummy & ii);
643 ii *= 2;
644 }
645 return ul;
646 }
647 else
648 {
649 ul = ul << 8;
650 ul |= tlli->b_cr_tlli[off1];
651 l -= 8;
652 if(l EQ 0)
653 return ul;
654 }
655 }
656 while(TRUE);
657 }
658
659
660
661 /*
662 +------------------------------------------------------------------------------
663 | Function : grlc_delete_prim
664 +------------------------------------------------------------------------------
665 | Description : The function grlc_delete_prim() deletes the primitive that is
666 | pointed by the grlc_data->prim_start_tbf and sets the
667 | grlc_data->prim_start_tbf to the next entry in the tbf list.
668 |
669 | Parameters : void
670 |
671 +------------------------------------------------------------------------------
672 */
673 GLOBAL void grlc_delete_prim ( void )
674 {
675 TRACE_FUNCTION( "grlc_delete_prim" );
676
677 /*
678 * access type is reseted
679 */
680 grlc_data->uplink_tbf.access_type = CGRLC_AT_NULL;
681
682 if(grlc_data->prim_start_tbf < PRIM_QUEUE_SIZE_TOTAL)
683 {
684 UBYTE i;
685
686 /*
687 * get first entry from tbf list
688 */
689 i = grlc_prim_get_first (&grlc_data->prim_start_tbf);
690
691
692 if(i >= PRIM_QUEUE_SIZE)
693 {
694 TRACE_EVENT_P5("delete prim VOR i=%d ps=%d, pf=%d,sps=%d,spf=%d",
695 i,
696 grlc_data->prim_start_tbf,
697 grlc_data->prim_start_free,
698 grlc_data->save_prim_start_tbf,
699 grlc_data->save_prim_start_free);
700 }
701
702 /*
703 * estimate new user data amount in queue
704 */
705 grlc_data->prim_user_data -= BYTELEN(grlc_data->prim_queue[i].prim_ptr->sdu.l_buf);
706
707 /*
708 * free primitive before reset old primitive entry
709 */
710 PFREE ( grlc_data->prim_queue[i].prim_ptr );
711
712 /*
713 * reset old primitive
714 */
715 grlc_data->prim_queue[i].prim_ptr = NULL;
716 grlc_data->prim_queue[i].prim_type = CGRLC_LLC_PRIM_TYPE_NULL;
717 grlc_data->prim_queue[i].cv_status = FALSE;
718 grlc_data->prim_queue[i].rlc_status = FALSE;
719 grlc_data->prim_queue[i].re_allocation = FALSE;
720 grlc_data->prim_queue[i].start_new_tbf = FALSE;
721 grlc_data->prim_queue[i].last_bsn = 0xff;
722 grlc_data->prim_queue[i].previous = 0xff;
723
724 /*
725 * put new entry at the end of free list
726 */
727
728 if(i < PRIM_QUEUE_SIZE)
729 {
730 grlc_prim_put(&grlc_data->prim_start_free,i,END_OF_LIST);
731 }
732 else if(grlc_data->gmm_procedure_is_running)
733 {
734 grlc_prim_put(&grlc_data->prim_start_free,i,END_OF_LIST);
735 TRACE_EVENT_P5("delete prim %d AFTER PST=%d, PSF=%d,spst=%d,spsf=%d",
736 i,
737 grlc_data->prim_start_tbf,
738 grlc_data->prim_start_free,
739 grlc_data->save_prim_start_tbf,
740 grlc_data->save_prim_start_free);
741 }
742
743 /*
744 * update LLC flow control state
745 */
746 if ((grlc_data->tm.send_grlc_ready_ind EQ PRIM_QUEUE_FULL) AND /* PRIM QUEUE IS FULL */
747 (
748 (!grlc_data->gmm_procedure_is_running AND (i < PRIM_QUEUE_SIZE)) OR /* LLC QUEUE IS ACTIVE, PDU FROM LLC QUEUE DELETED */
749 (grlc_data->gmm_procedure_is_running AND !(i < PRIM_QUEUE_SIZE)))) /* GMM QUEUE IS ACTIVE, PDU FROM GMM QUEUE DELETED */
750 {
751 TRACE_EVENT_P3("Flow control activated gmm_q=%d,i=%d,ready=%d",grlc_data->gmm_procedure_is_running,i,grlc_data->tm.send_grlc_ready_ind);
752 grlc_data->tm.send_grlc_ready_ind = SEND_A_GRLC_READY_IND;
753 }
754
755 grlc_data->grlc_data_req_cnt--;
756 }
757 else
758 {
759 TRACE_EVENT_P3("PST=%d PSF=%d PDU=%d: grlc_delete_prim"
760 ,grlc_data->prim_start_tbf
761 ,grlc_data->prim_start_free
762 ,grlc_data->grlc_data_req_cnt);
763 return;
764 }
765
766
767 } /* grlc_delete_prim() */
768
769
770
771
772
773
774
775 /*
776 +------------------------------------------------------------------------------
777 | Function : grlc_calc_new_poll_pos
778 +------------------------------------------------------------------------------
779 | Description : The function grlc_calc_new_poll_pos() calculates the fn of the
780 | new poll position
781 |
782 | Parameters : fn_i - framenumber
783 | rrbp_i - relative position
784 |
785 +------------------------------------------------------------------------------
786 */
787 GLOBAL ULONG grlc_calc_new_poll_pos ( ULONG fn_i, UBYTE rrbp_i )
788 {
789 ULONG result=0;
790 TRACE_FUNCTION( "grlc_calc_new_poll_pos" );
791
792 switch( rrbp_i )
793 {
794 case 0:
795 result = (fn_i+13);
796 break;
797 case 1:
798 if((fn_i+18)%13)
799 result = (fn_i+17);
800 else
801 result = (fn_i+18);
802 break;
803 case 2:
804 if(((fn_i+21)%13) EQ 8)
805 result = (fn_i+21);
806 else
807 result = (fn_i+22);
808 break;
809 case 3:
810 result = (fn_i+26);
811 break;
812 default:
813 TRACE_ERROR( "unexpected rrbp value" );
814 break;
815 } /* switch (rrbp_i) */
816 result = result % 0x297000;
817
818 return result;
819
820 } /* grlc_calc_new_poll_pos() */
821
822
823
824
825 /*
826 +------------------------------------------------------------------------------
827 | Function : grlc_get_new_poll_index
828 +------------------------------------------------------------------------------
829 | Description : The function grlc_get_new_poll_index()
830 |
831 | Parameters :
832 |
833 +------------------------------------------------------------------------------
834 */
835 LOCAL UBYTE grlc_get_new_poll_index ( UBYTE * ptr_list_start_i )
836 {
837 UBYTE result;
838 TRACE_FUNCTION( "grlc_get_new_poll_index" );
839
840 result = *ptr_list_start_i;
841 /* set to new first entry */
842 if (result NEQ 0xFF)
843 {
844 *ptr_list_start_i = grlc_data->next_poll_array[*ptr_list_start_i].next;
845 /* remove first entry from list */
846 grlc_data->next_poll_array[result].next = 0xff;
847 }
848 else
849 {
850 TRACE_EVENT ("Poll array is full");
851 }
852
853 return(result);
854
855 } /* grlc_get_new_poll_index() */
856
857
858
859
860 /*
861 +------------------------------------------------------------------------------
862 | Function : grlc_save_poll_pos
863 +------------------------------------------------------------------------------
864 | Description : The function grlc_save_poll_pos()
865 |
866 | Parameters : fn_i - framenumber
867 | tn_i - timeslot number
868 | rrbp_i - fn of the poll block|
869 | poll_type_i - kind of dl data
870 | pctrl_ack_i - packet control ack value, needed fo p ctr ack msg
871 |
872 |
873 +------------------------------------------------------------------------------
874 */
875 GLOBAL void grlc_save_poll_pos ( ULONG fn_i, USHORT tn_i, UBYTE rrbp_i, UBYTE poll_type_i,UBYTE pctrl_ack_i)
876 {
877 ULONG new_poll_pos;
878 UBYTE i, next, help_index;
879
880 TRACE_FUNCTION( "grlc_save_poll_pos" );
881
882 if( tn_i >= POLL_TYPE_ARRAY_SIZE )
883 {
884 TRACE_EVENT_P5( "grlc_save_poll_pos: fn = %d, tn = %d, rrbp = %d, poll_type = %d, pctrl_ack = %d",
885 fn_i, tn_i, rrbp_i, poll_type_i, pctrl_ack_i );
886
887 return;
888 }
889
890 if(0xFF NEQ rrbp_i)
891 {
892 new_poll_pos = grlc_calc_new_poll_pos(fn_i, rrbp_i);
893 }
894 else
895 {
896 new_poll_pos = fn_i;
897 }
898
899 /*TRACE_EVENT_P6("SAVE BEF: fn_i= %ld,rrbp=%ld,new_poll_pos=%ld, poll_type=%d,ps=%d ps_fn=%ld",
900 fn_i,
901 rrbp_i,
902 new_poll_pos,
903 poll_type_i,
904 grlc_data->poll_start_tbf,
905 grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn);
906
907 */
908 /* delete the poll position when it is older than 26 frames */
909 while( grlc_data->poll_start_tbf NEQ 0xFF AND
910 grlc_check_dist(new_poll_pos,
911 grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn, 26) EQ FALSE)
912 {
913 /* move the expired poll position to the list of unused entries */
914 TRACE_EVENT_P1("Remove expired poll at pst=%d",grlc_data->poll_start_tbf);
915 help_index = grlc_data->poll_start_tbf;
916 grlc_data->poll_start_tbf = grlc_data->next_poll_array[help_index].next;
917 grlc_data->next_poll_array[help_index].next = grlc_data->poll_start_free;
918 grlc_data->poll_start_free = help_index;
919
920 /* clear the poll position */
921 grlc_data->next_poll_array[help_index].fn = 0xFFFFFFFF;
922 grlc_data->next_poll_array[help_index].cnt = 0;
923
924 for( i = 0; i < POLL_TYPE_ARRAY_SIZE; i++ )
925 {
926 grlc_data->next_poll_array[help_index].poll_type[i] = CGRLC_POLL_NONE;
927 }
928 }
929
930 next = 0xFF;
931 help_index = grlc_data->poll_start_tbf;
932
933
934 /*
935 * find the position of the new fn
936 */
937
938 while( help_index NEQ 0xFF )
939 {
940 if( grlc_data->next_poll_array[help_index].fn EQ new_poll_pos )
941 {
942 next = help_index;
943 help_index = 0xFF;
944 }
945 else if( grlc_check_dist( new_poll_pos, grlc_data->next_poll_array[help_index].fn, 26 ) )
946 {
947 next = help_index;
948 help_index = grlc_data->next_poll_array[help_index].next;
949 }
950 else
951 {
952 help_index = 0xFF;
953 }
954 }
955
956 /*
957 * new_poll_pos is present in the poll array
958 */
959 if( next NEQ 0xFF AND
960 grlc_data->next_poll_array[next].fn EQ new_poll_pos AND
961 grlc_data->next_poll_array[next].poll_type[tn_i] EQ CGRLC_POLL_NONE )
962 {
963 /*
964 * no collision
965 */
966 grlc_data->next_poll_array[next].poll_type[tn_i] = poll_type_i;
967 grlc_data->next_poll_array[next].cnt++;
968 grlc_data->next_poll_array[next].ctrl_ack = pctrl_ack_i;
969 }
970 else if( next NEQ 0xFF AND
971 grlc_data->next_poll_array[next].fn EQ new_poll_pos )
972
973 {
974 /*
975 * collision detected, if both pos were received with data blocks, the sent
976 * RLC/MAC block otherwise send packet control ack.
977 */
978 if ((poll_type_i NEQ CGRLC_POLL_DATA)
979 OR
980 (grlc_data->next_poll_array[next].poll_type[tn_i] NEQ CGRLC_POLL_DATA))
981 {
982 grlc_data->next_poll_array[next].poll_type[tn_i] = CGRLC_POLL_COLLISION;
983 TRACE_EVENT("collision detected: pca will sent");
984 }
985 else
986 {
987 TRACE_EVENT("collision detected: rlc/mac will be sent");
988 }
989 if(pctrl_ack_i NEQ 3)
990 grlc_data->next_poll_array[next].ctrl_ack = pctrl_ack_i;
991 }
992 else
993 {
994 /*
995 * fn does not exist in the poll list, included in poll list
996 *
997 * get new free index from the free list
998 */
999 i = grlc_get_new_poll_index(&(grlc_data->poll_start_free));
1000 if( i EQ 0xFF )
1001 {
1002 TRACE_EVENT ("Poll array is full"); /*This should not happen */
1003 return;
1004 }
1005
1006 grlc_data->next_poll_array[i].cnt = 1;
1007 grlc_data->next_poll_array[i].fn = new_poll_pos;
1008 grlc_data->next_poll_array[i].poll_type[tn_i] = poll_type_i;
1009 grlc_data->next_poll_array[i].ctrl_ack = pctrl_ack_i;
1010
1011 if( next EQ 0xFF )
1012 {
1013 /*
1014 * first entry in poll array
1015 */
1016 grlc_data->next_poll_array[i].next = grlc_data->poll_start_tbf;
1017 grlc_data->poll_start_tbf = i;
1018 }
1019 else if( next < NEXT_POLL_ARRAY_SIZE )
1020 {
1021 /*
1022 * include in description list, is not first element
1023 */
1024 grlc_data->next_poll_array[i].next = grlc_data->next_poll_array[next].next;
1025 grlc_data->next_poll_array[next].next = i;
1026 }
1027 else
1028 {
1029 TRACE_ASSERT( next < NEXT_POLL_ARRAY_SIZE );
1030 }
1031 }
1032
1033
1034 /*TRACE_EVENT_P6("SAVE AFTER: fn_i= %ld,rrbp=%ld,new_poll_pos=%ld, poll_type=%d,ps=%d ps_fn=%ld",
1035 fn_i,
1036 rrbp_i,
1037 new_poll_pos,
1038 poll_type_i,
1039 grlc_data->poll_start_tbf,
1040 grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn);
1041 */
1042
1043 } /* grlc_save_poll_pos() */
1044
1045
1046
1047
1048
1049
1050 /*
1051 +------------------------------------------------------------------------------
1052 | Function : grlc_encode_ctrl
1053 +------------------------------------------------------------------------------
1054 | Description : The function grlc_encode_ctrl() build a T_SDU buffer that
1055 | contains the encode Ctrl Block ready to transmit.
1056 |
1057 | Parameters : ULONG ptr_in_i - ptr to the input structure
1058 | ULONG ptr_out_i - ptr to begin of output buffer
1059 | UBYTE r_bit_i - value of r_bit
1060 +------------------------------------------------------------------------------
1061 */
1062 GLOBAL void grlc_encode_ctrl ( UBYTE * ptr_in_i,
1063 T_MSGBUF * ptr_out_i,
1064 UBYTE r_bit_i)
1065 {
1066 TRACE_FUNCTION( "grlc_encode_ctrl" );
1067
1068 ptr_out_i->buf[0] = 0x40 | r_bit_i;
1069 ptr_out_i->o_buf = BIT_UL_CTRL_BLOCK_MAC_HEADER;
1070 ptr_out_i->l_buf = BIT_UL_CTRL_BLOCK_CONTENTS;
1071
1072
1073 if(!grlc_data->grlc_wo_ccd)
1074 {
1075 ccd_codeMsg ( CCDENT_GRLC,
1076 UPLINK,
1077 ptr_out_i,
1078 ptr_in_i,
1079 NOT_PRESENT_8BIT);
1080 }
1081 else
1082 {
1083 switch(ptr_in_i[0]) /* msg_type */
1084 {
1085 case U_GRLC_UL_DUMMY_c:
1086 grlc_encode_ul_dummy(&ptr_out_i->buf[1]);
1087 break;
1088 case U_GRLC_CTRL_ACK_c:
1089 grlc_encode_pca(&ptr_out_i->buf[1]);
1090 break;
1091 case U_GRLC_DL_ACK_c:
1092 memset(&ptr_out_i->buf[1],0,22); /*lint !e419*/
1093 grlc_encode_dl_acknack(&ptr_out_i->buf[1]);
1094 break;
1095 default:
1096 ccd_codeMsg ( CCDENT_GRLC,
1097 UPLINK,
1098 ptr_out_i,
1099 ptr_in_i,
1100 NOT_PRESENT_8BIT);
1101 break;
1102 }
1103 }
1104 ptr_out_i->l_buf += ptr_out_i->o_buf;
1105 ptr_out_i->o_buf = 0;
1106
1107 } /* grlc_encode_ctrl() */
1108
1109
1110 /*
1111 +------------------------------------------------------------------------------
1112 | Function : grlc_init
1113 +------------------------------------------------------------------------------
1114 | Description : The function grlc_init initializes the entity GRLC
1115 |
1116 | Parameters : void
1117 |
1118 +------------------------------------------------------------------------------
1119 */
1120 GLOBAL void grlc_init ( void )
1121 {
1122 TRACE_FUNCTION( "grlc_init" );
1123
1124 /* initialize all GRLC data */
1125 grlc_data = &grlc_data_base;
1126 memset( grlc_data, 0, sizeof( T_GRLC_DATA ) );
1127
1128 grlc_data->grlc_data_req_cnt = 0;
1129 grlc_data->testmode.mode = CGRLC_NO_TEST_MODE;
1130
1131 grlc_data->meas.sq_restart = TRUE;
1132
1133 /*
1134 * call of service init functions
1135 */
1136 tm_grlc_init();
1137 rd_init();
1138 ru_init();
1139 meas_grlc_init();
1140 tpc_grlc_init();
1141 gff_init();
1142
1143 ccd_register(CCD_REENTRANT);
1144
1145 #ifdef _SIMULATION_
1146 /*
1147 * to make sure that the structure definitions of T_GRLC_DATA_REQ and
1148 * T_GRLC_UNITDATA_REQ have the same layout.
1149 */
1150 {
1151 T_GRLC_DATA_REQ * ptr_grlc_data_req = (T_GRLC_DATA_REQ *)_decodedMsg;
1152 T_GRLC_UNITDATA_REQ * ptr_grlc_unitdata_req = (T_GRLC_UNITDATA_REQ *)_decodedMsg;
1153
1154 if( &(ptr_grlc_data_req->grlc_qos) NEQ &(ptr_grlc_unitdata_req->grlc_qos) AND
1155 &(ptr_grlc_data_req->radio_prio) NEQ &(ptr_grlc_unitdata_req->radio_prio) AND
1156 &(ptr_grlc_data_req->sdu) NEQ &(ptr_grlc_unitdata_req->sdu) AND
1157 &(ptr_grlc_data_req->tlli) NEQ &(ptr_grlc_unitdata_req->tlli) )
1158 {
1159 /*
1160 * In this case the primitive handling will not work correctly!!!
1161 */
1162 TRACE_ERROR("Fatal ERROR: T_GRLC_UNITDATA_REQ and T_GRLC_DATA_REQ are not equal!!");
1163 }
1164 } /* _SIMULATION_ */
1165 #endif
1166
1167 grlc_data->t3164_to_cnt = 0;
1168 grlc_data->ul_tfi_changed = FALSE;
1169 grlc_data->uplink_tbf.access_type = CGRLC_AT_NULL; /* NO CELL UPDATE NEED */
1170 grlc_data->grlc_wo_ccd = 0; /* as default ccd used for air message handling */
1171
1172 /*
1173 * Ready Timer state initialization
1174 */
1175 #ifdef FF_GRLC_4_TWO_2_ONE
1176 grlc_data->ready_timer.handling = READY_TIMER_HANDLING_ENABLED;
1177 #else
1178 grlc_data->ready_timer.handling = READY_TIMER_HANDLING_DISABLED;
1179 #endif
1180
1181 grlc_data->ready_timer.state = STANDBY_STATE;
1182 grlc_data->ready_timer.value = CGRLC_T3314_DEFAULT;
1183
1184 } /* grlc_init() */
1185
1186
1187
1188 /*
1189 +------------------------------------------------------------------------------
1190 | Function : grlc_prim_put
1191 +------------------------------------------------------------------------------
1192 | Description : The function grlc_prim_put() put a Element (object_i) behind
1193 | pos_i in the prim_queue.
1194 |
1195 | Parameters : list_start_i - address of the list should be manipulted
1196 | object_i - index of element that should be added to the list
1197 | pos_i - index of the position behind that the object
1198 | should be added
1199 |
1200 +------------------------------------------------------------------------------
1201 */
1202 GLOBAL void grlc_prim_put(UBYTE * list_start_i, UBYTE object_i, UBYTE pos_i)
1203 {
1204 TRACE_FUNCTION( "grlc_prim_put" );
1205
1206 if(* list_start_i EQ 0xff)
1207 { /* no elements in the list */
1208 * list_start_i = object_i;
1209 }
1210 else
1211 { /* elements in the list */
1212 UBYTE i = * list_start_i;
1213 UBYTE j;
1214 BOOL put= FALSE;
1215
1216 /*
1217 * SZML-GLBL/004
1218 */
1219 for(j=0;j<PRIM_QUEUE_SIZE_TOTAL;j++)
1220 {
1221 if (grlc_data->prim_queue[i].next NEQ pos_i)
1222 {
1223 i = grlc_data->prim_queue[i].next;
1224 }
1225 else
1226 {
1227 /*
1228 * put new object at pos_i of queue
1229 */
1230 put = TRUE;
1231 grlc_data->prim_queue[object_i].next = grlc_data->prim_queue[i].next;
1232 grlc_data->prim_queue[i].next = object_i;
1233 break;
1234 }
1235 }
1236 if(!put)
1237 TRACE_EVENT_P3("PST=%d PSF=%d PDU=%d: grlc_prim_put failed"
1238 ,grlc_data->prim_start_tbf
1239 ,grlc_data->prim_start_free
1240 ,grlc_data->grlc_data_req_cnt);
1241
1242 }
1243 } /* grlc_prim_put() */
1244
1245
1246
1247 /*
1248 +------------------------------------------------------------------------------
1249 | Function : grlc_prim_get_first
1250 +------------------------------------------------------------------------------
1251 | Description : The function grlc_prim_get_first() removes the first element
1252 | and returns the index of the first element.
1253 |
1254 | Parameters : list_start_i - address of the list that should be used
1255 |
1256 +------------------------------------------------------------------------------
1257 */
1258 GLOBAL UBYTE grlc_prim_get_first(UBYTE * list_start_i)
1259 {
1260 UBYTE result;
1261 TRACE_FUNCTION( "grlc_prim_get_first" );
1262
1263 result = *list_start_i;
1264
1265 /*
1266 * set to new first entry
1267 */
1268 *list_start_i = grlc_data->prim_queue[*list_start_i].next;
1269
1270 /*
1271 * remove first entry from list
1272 */
1273 grlc_data->prim_queue[result].next = 0xff;
1274
1275 return(result);
1276
1277 } /* grlc_prim_get_first() */
1278
1279
1280 /*
1281 +------------------------------------------------------------------------------
1282 | Function : grlc_set_packet_ctrl_ack
1283 +------------------------------------------------------------------------------
1284 | Description : The function grlc_set_packet_ctrl_ack() |
1285 | Parameters :
1286 |
1287 +------------------------------------------------------------------------------
1288 */
1289 GLOBAL UBYTE * grlc_set_packet_ctrl_ack(void)
1290 {
1291 MCAST(u_ctrl_ack,U_GRLC_CTRL_ACK);
1292 UBYTE * result;
1293 TRACE_FUNCTION( "grlc_set_packet_ctrl_ack" );
1294
1295 u_ctrl_ack->msg_type = U_GRLC_CTRL_ACK_c;
1296
1297 grlc_set_buf_tlli( &u_ctrl_ack->tlli_value, grlc_data->uplink_tbf.tlli );
1298
1299 if(grlc_data->poll_start_tbf NEQ 0xFF)
1300 u_ctrl_ack->pctrl_ack = grlc_data->next_poll_array[grlc_data->poll_start_tbf].ctrl_ack;
1301 else /* response to IA poll */
1302 u_ctrl_ack->pctrl_ack = 3;
1303
1304 result = _decodedMsg;
1305
1306 return(result);
1307
1308 } /* grlc_set_packet_ctrl_ack() */
1309
1310
1311
1312 /*
1313 +------------------------------------------------------------------------------
1314 | Function : grlc_send_access_burst
1315 +------------------------------------------------------------------------------
1316 | Description : The function grlc_send_access_burst() sents the poll as
1317 | four access burst type
1318 |
1319 | Parameters : tn_i : timeslot where the access burst shall send
1320 |
1321 +------------------------------------------------------------------------------
1322 */
1323 GLOBAL void grlc_send_access_burst(UBYTE tn_i)
1324 {
1325 TRACE_FUNCTION( "grlc_send_access_burst" );
1326
1327
1328
1329 if(grlc_data->poll_start_tbf NEQ 0xFF)
1330 {
1331 grlc_data->next_poll_array[grlc_data->poll_start_tbf].cnt--;
1332 grlc_data->next_poll_array[grlc_data->poll_start_tbf].poll_type[tn_i] = CGRLC_POLL_NONE;
1333 grlc_data->next_poll_fn = grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn;
1334 }
1335 grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index].tn = tn_i;
1336 if(grlc_data->ab_type EQ CGRLC_AB_11_BIT)
1337 {
1338 /*11 bit access burst*/
1339 USHORT elevenBit = 0x07E4+grlc_data->next_poll_array[grlc_data->poll_start_tbf].ctrl_ack;
1340 grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index].block_status = 8;
1341 grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index].ul_block[0] = grlc_convert_11bit_2_etsi(elevenBit);
1342 /*
1343 TRACE_EVENT_P2("PCA AB_11_BIT sent fn_i= %ld PRACH11: %d"
1344 ,grlc_data->next_poll_fn
1345 ,grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index].ul_block[0]);
1346 */
1347 }
1348 else
1349 {
1350 /*8 bit access burst*/
1351 grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index].block_status = 7;
1352 grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index].ul_block[0] = (0x7C+grlc_data->next_poll_array[grlc_data->poll_start_tbf].ctrl_ack);
1353 /*
1354 TRACE_EVENT_P1 ("PCA 8 bit access burst sent fn_i= %ld ",grlc_data->next_poll_fn);
1355 */
1356 }
1357
1358 #ifdef _SIMULATION_
1359 {
1360 PALLOC(mac_poll_req,MAC_POLL_REQ);
1361 memset(mac_poll_req,0,
1362 sizeof(T_MAC_POLL_REQ));
1363 memcpy(&(mac_poll_req->ul_poll_resp),
1364 &(grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index]),
1365 sizeof(T_ul_poll_resp));
1366 PSEND(hCommL1,mac_poll_req);
1367 }
1368 #else /* #ifdef _SIMULATION_ */
1369 {
1370 TRACE_MEMORY_PRIM ( hCommGRLC, hCommL1, MAC_POLL_REQ,
1371 &grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index],
1372 sizeof(T_ul_poll_resp) );
1373 }
1374 #endif /* #ifdef _SIMULATION_ */
1375
1376 TRACE_BINDUMP
1377 ( hCommGRLC, TC_USER4,
1378 cl_rlcmac_get_msg_name( U_MSG_TYPE_CHANNEL_REQ_c, RLC_MAC_ROUTE_UL ),
1379 grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index].ul_block,
1380 RLC_MAC_MAX_LEN_CHANNEL_REQ ); /*lint !e569*/
1381
1382 grlc_data->ul_poll_pos_index++;
1383 /*
1384 * next poll block invalid
1385 */
1386 grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index].block_status = 0;
1387
1388
1389 } /* grlc_send_access_burst() */
1390
1391 /*
1392 +------------------------------------------------------------------------------
1393 | Function : grlc_send_normal_burst
1394 +------------------------------------------------------------------------------
1395 | Description : The function grlc_send_normal_burst() sents the poll as
1396 | normal burst type
1397 |
1398 | Parameters : ptr_block_i : ptr to the ctrl message
1399 | Parameters : tn_i : timeslot where the access burst shall send
1400 | Parameters : r_bit_i : r bit needed for the mac header
1401 |
1402 +------------------------------------------------------------------------------
1403 */
1404 GLOBAL void grlc_send_normal_burst
1405 (UBYTE * struct_data, UBYTE * encoded_data, UBYTE tn_i)
1406 {
1407
1408 TRACE_FUNCTION( "grlc_send_normal_burst" );
1409
1410 if( (grlc_data->poll_start_tbf NEQ 0xFF) AND
1411 (grlc_data->ta_value EQ 0xFF) )
1412 {
1413 TRACE_EVENT_P2("No TA VALUE IN GRLC --> NB POLL NOT SENT ta=%d poll_st_tbf=%d"
1414 ,grlc_data->ta_value
1415 ,grlc_data->poll_start_tbf);
1416
1417 TRACE_ERROR("No TA VALUE IN GRLC --> NB POLL NOT SENT");
1418
1419 grlc_data->next_poll_array[grlc_data->poll_start_tbf].cnt--;
1420 grlc_data->next_poll_array[grlc_data->poll_start_tbf].poll_type[tn_i] = CGRLC_POLL_NONE;
1421 return;
1422 }
1423
1424 /*
1425 * either encoded data or structured data are passed by reference
1426 */
1427
1428
1429 if( struct_data NEQ NULL )
1430 {
1431 grlc_encode_ul_ctrl_block( ( UBYTE* )grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index].ul_block, struct_data );
1432 }
1433 else if( encoded_data NEQ NULL )
1434 {
1435 memcpy( ( UBYTE* )grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index].ul_block,
1436 encoded_data,
1437 BYTE_UL_CTRL_BLOCK );
1438 }
1439 else
1440 {
1441 TRACE_ERROR( "grlc_send_normal_burst: no data available" );
1442 }
1443
1444 grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index].tn = tn_i;
1445 grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index].block_status = 3;
1446
1447 if(grlc_data->poll_start_tbf NEQ 0xFF)
1448 {
1449 grlc_data->next_poll_array[grlc_data->poll_start_tbf].cnt--;
1450 grlc_data->next_poll_array[grlc_data->poll_start_tbf].poll_type[tn_i] = CGRLC_POLL_NONE;
1451 grlc_data->next_poll_fn = grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn;
1452 }
1453
1454 #ifdef _SIMULATION_
1455 {
1456 PALLOC(mac_poll_req,MAC_POLL_REQ);
1457 memset(mac_poll_req,0,
1458 sizeof(T_MAC_POLL_REQ));
1459 memcpy(&(mac_poll_req->ul_poll_resp),
1460 &(grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index]),
1461 sizeof(T_ul_poll_resp));
1462 PSEND(hCommL1,mac_poll_req);
1463 }
1464 #else /* #ifdef _SIMULATION_ */
1465 {
1466 TRACE_MEMORY_PRIM ( hCommGRLC, hCommL1, MAC_POLL_REQ,
1467 &grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index],
1468 sizeof(T_ul_poll_resp) );
1469 }
1470 #endif /* #ifdef _SIMULATION_ */
1471
1472 {
1473 UBYTE* ul_block = ( UBYTE* )grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index].ul_block;
1474
1475 TRACE_BINDUMP( hCommGRLC, TC_USER4,
1476 cl_rlcmac_get_msg_name
1477 ( ( UBYTE )( ul_block[1] >> 2 ), RLC_MAC_ROUTE_UL ),
1478 ul_block, MAX_L2_FRAME_SIZE ); /*lint !e569*/
1479 }
1480
1481 grlc_data->ul_poll_pos_index++;
1482 /*
1483 * next poll block invalid
1484 */
1485 grlc_data->ul_poll_resp[grlc_data->ul_poll_pos_index].block_status = 0;
1486
1487 /*
1488 TRACE_EVENT_P1 ("Normal burst sent at fn_i= %ld ",grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn);
1489 */
1490 } /* grlc_send_normal_burst() */
1491
1492 /*
1493 +------------------------------------------------------------------------------
1494 | Function : grlc_del_sent_poll
1495 +------------------------------------------------------------------------------
1496 | Description : The function grlc_del_sent_poll() deletes the poll pos which was
1497 | sent to L1
1498 |
1499 | Parameters
1500
1501 |
1502 +------------------------------------------------------------------------------
1503 */
1504 GLOBAL void grlc_del_sent_poll(void )
1505 {
1506 UBYTE help_index;
1507 UBYTE next_index;
1508
1509 TRACE_FUNCTION( "grlc_del_sent_poll" );
1510
1511
1512 if( grlc_data->next_poll_array[grlc_data->poll_start_tbf].cnt EQ 0 )
1513 {
1514 help_index = grlc_data->poll_start_tbf;
1515 grlc_data->poll_start_tbf = grlc_data->next_poll_array[grlc_data->poll_start_tbf].next;
1516 next_index = grlc_data->poll_start_free;
1517 while(grlc_data->next_poll_array[next_index].next NEQ 0xFF)
1518 {
1519 next_index = grlc_data->next_poll_array[next_index].next;
1520 }
1521 grlc_data->next_poll_array[next_index].next = help_index;
1522 grlc_data->next_poll_array[help_index].next = 0xFF;
1523 }
1524
1525
1526
1527 } /* grlc_del_sent_poll() */
1528
1529
1530
1531 /*
1532 +------------------------------------------------------------------------------
1533 | Function : grlc_decode_tbf_start_rel
1534 |------------------------------------------------------------------------------
1535 | Description : The function grlc_decode_tbf_start_rel() translates the TBF-
1536 | Starting-Time-Relative into full frame number. Therefore the
1537 | received frame number is needed in start_fn !!
1538 |
1539 | Parameters : rel_pos - number in blocks added to current framenuber
1540 |
1541 +------------------------------------------------------------------------------
1542 */
1543 GLOBAL ULONG grlc_decode_tbf_start_rel(ULONG start_fn, USHORT rel_pos)
1544 {
1545 ULONG result;
1546
1547 TRACE_FUNCTION( "grlc_decode_tbf_start_rel" );
1548
1549 result = 4+4*rel_pos + start_fn + rel_pos/3;
1550
1551 if ((12 EQ (result%13)) OR
1552 (7 EQ (result%13)) OR
1553 (3 EQ (result%13)))
1554 {
1555 result += 1;
1556 }
1557 if(FN_MAX <= result)
1558 {
1559 result %= FN_MAX;
1560 }
1561
1562 return result;
1563 } /* grlc_decode_tbf_start_rel */
1564
1565
1566
1567 /*
1568 +------------------------------------------------------------------------------
1569 | Function : grlc_get_sdu_len_and_used_ts
1570 +------------------------------------------------------------------------------
1571 | Description :
1572 |
1573 | Parameters : * sdu_len - len of the current sdu in progress
1574 | * used_ul_resources - used uplink resources in fixed alloc mode
1575 |
1576 +------------------------------------------------------------------------------
1577 */
1578 GLOBAL void grlc_get_sdu_len_and_used_ts ( T_RLC_VALUES * values )
1579 {
1580 TRACE_FUNCTION( "grlc_get_sdu_len_and_used_ts" );
1581
1582 switch( GET_STATE( RU ) )
1583 {
1584 case RU_NULL:
1585 values->sdu_len = grlc_data->prim_queue[grlc_data->prim_start_tbf].prim_ptr->sdu.l_buf/8;
1586 values->cnt_ts = 0;
1587 break;
1588 default:
1589 values->sdu_len = grlc_data->ru.sdu_len;
1590 values->cnt_ts = grlc_data->ru.cnt_ts;
1591 break;
1592 }
1593 /* grlc_get_sdu_len_and_used_ts() */
1594 }
1595
1596
1597
1598 /*
1599 +------------------------------------------------------------------------------
1600 | Function : grlc_check_dist
1601 +------------------------------------------------------------------------------
1602 | Description : The function grlc_check_dist() checks if high_i is bigger/equal
1603 | than low_i(modulo calculation).
1604 | The return value is true, if high_i is equal to low_i or
1605 | bigger than low_i.
1606 | Parameters : high_i - expected high value
1607 | low_i - expected low value
1608 | dist_i - max. allowed distance between high_i and low_i
1609 +------------------------------------------------------------------------------
1610 */
1611 GLOBAL BOOL grlc_check_dist ( ULONG high_i, ULONG low_i, ULONG dist_i)
1612 {
1613 BOOL result = FALSE;
1614 ULONG real_dist;
1615
1616 TRACE_FUNCTION( "grlc_check_dist" );
1617
1618 if (high_i >= low_i)
1619 real_dist = high_i - low_i;
1620 else
1621 real_dist = high_i + (FN_MAX-low_i);
1622
1623 if (real_dist <= dist_i )
1624 {
1625 result = TRUE;
1626 }
1627 return result;
1628 } /* grlc_check_dist() */
1629
1630
1631
1632 /*
1633 +------------------------------------------------------------------------------
1634 | Function : grlc_handle_poll_pos
1635 +------------------------------------------------------------------------------
1636 | Description : The function grlc_handle_poll_pos()
1637 |
1638 | Parameters : -
1639 +------------------------------------------------------------------------------
1640 */
1641 GLOBAL void grlc_handle_poll_pos (ULONG current_fn)
1642 {
1643 UBYTE help_index;
1644 UBYTE next_index;
1645 TRACE_FUNCTION( "grlc_handle_poll_pos" );
1646
1647 while ( (grlc_data->poll_start_tbf NEQ 0xFF) AND
1648 (grlc_check_dist(current_fn,grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn,26)) AND
1649 (current_fn NEQ grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn))
1650 {
1651 TRACE_EVENT_P4("current_fn= %ld missed poll_fn=%ld ps_tbf=%d cnt=%d",
1652 current_fn,
1653 grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn,
1654 grlc_data->poll_start_tbf,
1655 grlc_data->next_poll_array[grlc_data->poll_start_tbf].cnt);
1656 /*
1657 * delete elememnt from tbf_list if all pollType = POLL_NONE, and add to free list
1658 */
1659 grlc_data->missed_poll_fn = grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn;
1660 grlc_data->next_poll_array[grlc_data->poll_start_tbf].cnt = 0;
1661 help_index = grlc_data->poll_start_tbf;
1662 grlc_data->poll_start_tbf = grlc_data->next_poll_array[grlc_data->poll_start_tbf].next;
1663 next_index = grlc_data->poll_start_free;
1664 while(grlc_data->next_poll_array[next_index].next NEQ 0xFF)
1665 {
1666 next_index = grlc_data->next_poll_array[next_index].next;
1667 }
1668 grlc_data->next_poll_array[next_index].next = help_index;
1669 grlc_data->next_poll_array[help_index ].next = 0xFF;
1670 TRACE_ERROR( "Poll Position missed" );
1671 }
1672 } /* grlc_handle_poll_pos() */
1673
1674
1675 /*
1676 +------------------------------------------------------------------------------
1677 | Function : grlc_send_rem_poll_pos
1678 +------------------------------------------------------------------------------
1679 | Description : The function grlc_send_rem_poll_pos()
1680 |
1681 | Parameters : -
1682 +------------------------------------------------------------------------------
1683 */
1684 GLOBAL void grlc_send_rem_poll_pos (ULONG current_fn)
1685 {
1686 ULONG delta_fn = 0;
1687 UBYTE *ptr_block=NULL;
1688
1689
1690 TRACE_FUNCTION( "grlc_send_rem_poll_pos" );
1691
1692 if (grlc_data->poll_start_tbf EQ 0xFF)
1693 return;
1694
1695
1696
1697 #ifdef _TARGET_
1698 delta_fn = grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn;
1699 if(current_fn EQ FN_MAX-5)
1700 delta_fn += 5;
1701 else
1702 delta_fn -= current_fn;
1703 #endif
1704
1705 #ifdef _SIMULATION_
1706 if(current_fn EQ grlc_data->next_poll_array[grlc_data->poll_start_tbf].fn)
1707 delta_fn = 4;
1708 else
1709 delta_fn = 0;
1710 #endif
1711
1712
1713 if( (delta_fn EQ 4) OR
1714 (delta_fn EQ 5) )
1715 {
1716 UBYTE tn=0;
1717 UBYTE index;
1718 while(grlc_data->next_poll_array[grlc_data->poll_start_tbf].cnt
1719 AND (tn < 8))
1720 {
1721 switch(grlc_data->next_poll_array[grlc_data->poll_start_tbf].poll_type[tn])
1722 {
1723 case CGRLC_POLL_CTRL:
1724 case CGRLC_POLL_UACK:
1725 case CGRLC_POLL_COLLISION:
1726 if(grlc_data->burst_type EQ CGRLC_BURST_TYPE_NB)
1727 {
1728 ptr_block = grlc_set_packet_ctrl_ack();
1729 grlc_send_normal_burst(ptr_block, NULL, tn);
1730 }
1731 else
1732 grlc_send_access_burst(tn);
1733 break;
1734 case CGRLC_POLL_RES_AB:
1735 grlc_send_access_burst(tn);
1736 break;
1737 case CGRLC_POLL_RES_NB:
1738 ptr_block = grlc_set_packet_ctrl_ack();
1739 grlc_send_normal_burst(ptr_block, NULL, tn);
1740 break;
1741 case CGRLC_POLL_DATA:
1742 if( grlc_data->tbf_type EQ TBF_TYPE_UL )
1743 {
1744 /*
1745 * no downlink active , send ctrl block or pca
1746 */
1747 if( tm_get_num_ctrl_blck( ) NEQ 0 )
1748 {
1749 ptr_block = tm_get_ctrl_blk( &index, TRUE );
1750 grlc_send_normal_burst(NULL, ptr_block, tn);
1751 grlc_data->rd.next_poll_block = NEXT_POLL_BLOCK_DL_DATA;
1752 }
1753 else if(grlc_data->burst_type EQ CGRLC_BURST_TYPE_NB)
1754 {
1755 ptr_block = grlc_set_packet_ctrl_ack();
1756 grlc_send_normal_burst(ptr_block, NULL, tn);
1757 }
1758 else
1759 grlc_send_access_burst(tn);
1760 }
1761 break;
1762 #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH
1763 case CGRLC_POLL_RE_ASS: /* TBF re assignment on PACCH */
1764
1765 if(grlc_data->burst_type EQ CGRLC_BURST_TYPE_NB)
1766 {
1767 T_U_GRLC_RESOURCE_REQ resource_req;
1768
1769 tm_build_res_req( &resource_req,R_BUILD_2PHASE_ACCESS);
1770 grlc_send_normal_burst((UBYTE *)&resource_req, NULL, tn);
1771 }
1772 else /* PCA CTRL ACK 00 */
1773 {
1774 grlc_data->next_poll_array[grlc_data->poll_start_tbf].ctrl_ack = 0;
1775 grlc_send_access_burst(tn);
1776 }
1777
1778 break;
1779 #endif
1780 }
1781 tn++;
1782 }
1783 grlc_del_sent_poll();
1784 }
1785 }/* grlc_send_rem_poll_pos() */
1786
1787
1788
1789 /*
1790 +------------------------------------------------------------------------------
1791 | Function : grlc_test_mode_active
1792 +------------------------------------------------------------------------------
1793 | Description : This functions returns 0 if the GPRS test mode is not activated.
1794 | Otherwise a value greater then 0.
1795 |
1796 | Parameters : no parameters
1797 |
1798 +------------------------------------------------------------------------------
1799 */
1800
1801 GLOBAL UBYTE grlc_test_mode_active ()
1802 {
1803 if(grlc_data->testmode.mode NEQ CGRLC_NO_TEST_MODE)
1804 return TRUE;
1805 else
1806 return FALSE;
1807
1808 }/* grlc_test_mode_active*/
1809
1810
1811 /*
1812 +------------------------------------------------------------------------------
1813 | Function : grlc_prbs
1814 +------------------------------------------------------------------------------
1815 | Description :
1816 | This function generates a pseodo random bis sequence.
1817 | The implementation is related to CCITT O.151 Okt. 92 chapter 2.1 .
1818 |
1819 | This functions generates the next length_i bytes of a 32767-bit
1820 | pseudo-random test sequence if action_i is set to COMPUTE_DATA
1821 | and writes the data at address ptr_i.
1822 |
1823 | The function stores the position where it stops to calculate.
1824 | In case of action_i EQ INITIALIZE the function erase his history.
1825 | On its next call the function continues with its intial values
1826 |
1827 | Parameters : UBYTE action_i (INITIALIZE or COMPUTE_DATA)
1828 | and only
1829 | UBYTE length_i (number of data bytes which shall callculated and copied)
1830 | UBYTE * out_i (location where this dada have to be placed, only valid)
1831 |
1832 +------------------------------------------------------------------------------
1833 */
1834
1835 GLOBAL void grlc_prbs(UBYTE action_i, UBYTE length_i, UBYTE * ptr_i)
1836 {
1837 TRACE_FUNCTION( "grlc_prbs" );
1838
1839 switch(action_i)
1840 {
1841 case INITIALIZE:
1842
1843 #define FEED_BACK_MASK 0x6000
1844 /*
1845 * 14th and 15 stage will be feeded back
1846 */
1847
1848
1849 /*
1850 * Initialize the prbs generation
1851 *
1852 * This value is the value of the shift register 8 cycles
1853 * before shift register value 0x7fff
1854 */
1855 grlc_data->testmode.prbs_shift_reg = 0x55ff;
1856 break;
1857 case COMPUTE_DATA:
1858 {
1859 /*
1860 * get prbs computing values
1861 */
1862 USHORT i,reg = grlc_data->testmode.prbs_shift_reg;
1863
1864 UBYTE * out_ptr = ptr_i;
1865
1866 for(i=0; i < (8 * length_i); i++)
1867 {
1868 /*
1869 * write a byte in output if neccessary
1870 */
1871 if(i % 8 EQ 0)
1872 {
1873 *out_ptr++ = (UBYTE)(0x00ff&reg);
1874 }
1875
1876
1877 {
1878 USHORT temp = reg & FEED_BACK_MASK;
1879 /*
1880 * shift the register and but new data in
1881 */
1882 reg = reg << 1;
1883 if ( (temp EQ FEED_BACK_MASK) OR (temp EQ 0) )
1884 {
1885 /*
1886 * put a "0" in
1887 */;
1888 }
1889 else
1890 {
1891 /*
1892 * put a "1" in
1893 */
1894 reg +=1;
1895 }
1896 } /* for(i=0; i < (8 * length_i); i++) */
1897 }
1898 /*
1899 * store prbs computing values
1900 */
1901 grlc_data->testmode.prbs_shift_reg = reg;
1902 }
1903 break;
1904
1905 default:
1906 break;
1907 }
1908
1909 return;
1910
1911 }/*grlc_prbs*/
1912
1913
1914
1915
1916
1917
1918
1919
1920 /*
1921 +------------------------------------------------------------------------------
1922 | Function : grlc_trace_tbf_par
1923 +------------------------------------------------------------------------------
1924 | Description :
1925 |
1926 | Parameters :
1927 |
1928 +------------------------------------------------------------------------------
1929 */
1930 GLOBAL void grlc_trace_tbf_par ( UBYTE tbf_index )
1931 {
1932 TRACE_FUNCTION( "grlc_trace_tbf_par" );
1933
1934 TRACE_EVENT_P9("tbf_type=%d;start_fn=%ld (%ld);end_fn=%ld(%ld);rlc_oct_cnt=%d; pdu_cnt=%ld;vs_vr=%d;va_vq=%d ",
1935 grlc_data->tbf_ctrl[tbf_index].tbf_type,
1936 grlc_data->tbf_ctrl[tbf_index].start_fn,
1937 grlc_data->tbf_ctrl[tbf_index].start_fn%42432,
1938 grlc_data->tbf_ctrl[tbf_index].end_fn,
1939 grlc_data->tbf_ctrl[tbf_index].end_fn%42432,
1940 grlc_data->tbf_ctrl[tbf_index].rlc_oct_cnt,
1941 grlc_data->tbf_ctrl[tbf_index].pdu_cnt,
1942 grlc_data->tbf_ctrl[tbf_index].vs_vr,
1943 grlc_data->tbf_ctrl[tbf_index].va_vq);
1944
1945 TRACE_EVENT_P9("cnt_ts=%d;ack_cnt=%d;fbi=%d;ret_bsn=%d;N_ACC=%d,tlli=%lx rem_ul_data=%d,PST=%d,PSF=%d",
1946 grlc_data->tbf_ctrl[tbf_index].cnt_ts,
1947 grlc_data->tbf_ctrl[tbf_index].ack_cnt,
1948 grlc_data->tbf_ctrl[tbf_index].fbi,
1949 grlc_data->tbf_ctrl[tbf_index].ret_bsn,
1950 grlc_data->tm.n_acc_req_procedures,
1951 grlc_data->uplink_tbf.tlli,
1952 grlc_data->grlc_data_req_cnt,
1953 grlc_data->prim_start_tbf,
1954 grlc_data->prim_start_free);
1955
1956 } /* grlc_trace_tbf_par */
1957
1958
1959
1960
1961 /*
1962 +------------------------------------------------------------------------------
1963 | Function : grlc_set_buf_tlli
1964 +------------------------------------------------------------------------------
1965 | Description : The function grlc_set_buf_tlli() fills the TLLI buffer.
1966 |
1967 | Parameters :
1968 |
1969 +------------------------------------------------------------------------------
1970 */
1971 GLOBAL void grlc_set_buf_tlli ( BUF_tlli_value *buf_tlli_o, ULONG tlli_i )
1972 {
1973 TRACE_FUNCTION( "grlc_set_buf_tlli" );
1974
1975 grlc_set_tlli( &buf_tlli_o->l_tlli_value,
1976 &buf_tlli_o->o_tlli_value,
1977 &buf_tlli_o->b_tlli_value[0],
1978 tlli_i );
1979
1980 } /* grlc_set_buf_tlli */
1981
1982
1983 /*
1984 +------------------------------------------------------------------------------
1985 | Function : grlc_set_tlli
1986 +------------------------------------------------------------------------------
1987 | Description : The function grlc_set_tlli() fills the TLLI buffer.
1988 |
1989 | Parameters :
1990 |
1991 +------------------------------------------------------------------------------
1992 */
1993 GLOBAL void grlc_set_tlli
1994 ( USHORT *l_tlli, USHORT *o_tlli, UBYTE *b_tlli, ULONG tlli )
1995 {
1996 TRACE_FUNCTION( "grlc_set_tlli" );
1997
1998 *l_tlli = 32;
1999 *o_tlli = 0;
2000
2001 b_tlli[0] = (UBYTE)((tlli >> 24) & 0x000000ff);
2002 b_tlli[1] = (UBYTE)((tlli >> 16) & 0x000000ff);
2003 b_tlli[2] = (UBYTE)((tlli >> 8 ) & 0x000000ff);
2004 b_tlli[3] = (UBYTE)((tlli ) & 0x000000ff);
2005
2006 /* unused byte must be set to 0x00, otherwise CCD has some problems */
2007 b_tlli[4] = 0;
2008
2009 } /* grlc_set_tlli */
2010
2011
2012 /*
2013 +------------------------------------------------------------------------------
2014 | Function : grlc_encode_ul_ctrl_block
2015 +------------------------------------------------------------------------------
2016 | Description :
2017 |
2018 | Parameters :
2019 |
2020 +------------------------------------------------------------------------------
2021 */
2022 GLOBAL void grlc_encode_ul_ctrl_block ( UBYTE *ul_ctrl_block,
2023 UBYTE *ul_ctrl_data )
2024 {
2025 T_CTRLBUF enc_block;
2026
2027 TRACE_FUNCTION( "grlc_encode_ul_ctrl_block" );
2028
2029 grlc_encode_ctrl( ul_ctrl_data, ( T_MSGBUF* )&enc_block , grlc_data->r_bit );
2030 memcpy( ul_ctrl_block, enc_block.buf, BYTELEN( enc_block.l_buf ) );
2031
2032 } /* grlc_encode_ul_ctrl_block */
2033
2034
2035
2036
2037
2038
2039 /*
2040 +------------------------------------------------------------------------------
2041 | Function : grlc_check_if_tbf_start_is_elapsed
2042 +------------------------------------------------------------------------------
2043 | Description : The function grlc_check_if_tbf_start_is_elapsed() checks if
2044 | tbf starting time is elapsed or not, modulo calculation is
2045 | needed
2046 | Parameters : start_fn - tbf starting time
2047 | current_fn - current frame number
2048 +------------------------------------------------------------------------------
2049 */
2050 GLOBAL BOOL grlc_check_if_tbf_start_is_elapsed ( ULONG start_fn, ULONG current_fn)
2051 {
2052 BOOL result = FALSE;
2053 ULONG d1;
2054 /* ULONG d2; */
2055 /* FN_MAX=0x297000 == 2715648 ==125463 seconds(4.62ms per frame)
2056 * the starting time is within current_fn-10808 and current_fn+31623
2057 * modulo operation must be taken in account
2058 */
2059 TRACE_FUNCTION( "grlc_check_if_tbf_start_is_elapsed" );
2060
2061 /*
2062 * handle maximum distance for tbf starting time
2063 */
2064
2065 if(start_fn EQ CGRLC_STARTING_TIME_NOT_PRESENT) /*lint !e650*/
2066 {
2067 result =TRUE;
2068 return result;
2069 }
2070 d1 = 10808;
2071 /* d2 = 31623; */
2072 if( (start_fn <= current_fn) AND
2073 ((current_fn-start_fn) <= d1))
2074 {
2075 result = TRUE;
2076 /*TRACE_EVENT_P2(" case 1: st time elapsed st_fn=%ld c_fn=%ld",start_fn,current_fn);*/
2077 }
2078 else if((start_fn >= current_fn) AND
2079 (FN_MAX-start_fn+current_fn) <= d1)
2080 {
2081 result = TRUE;
2082 /* TRACE_EVENT_P2("case 2: st time elapsed st_fn=%ld c_fn=%ld",start_fn,current_fn);*/
2083 }
2084 /* else
2085 {
2086 TRACE_EVENT_P2("case 3: WAIT FOR ST TIME st_fn=%ld c_fn=%ld",start_fn,current_fn);
2087 }
2088 */
2089
2090 return result;
2091 } /* grlc_check_if_tbf_start_is_elapsed() */
2092
2093
2094
2095 /*
2096 +------------------------------------------------------------------------------
2097 | Function : grlc_decode_grlc
2098 +------------------------------------------------------------------------------
2099 | Description : The function grlc_decode_grlc() calls the function ccd_decodeMsg.
2100 | After the call the decoded Message is in _decodeCtrlMsg.
2101 |
2102 | Parameters : msg_ptr_i - pointer to buffer that should be decoded
2103 |
2104 +------------------------------------------------------------------------------
2105 */
2106 GLOBAL UBYTE grlc_decode_grlc (T_MSGBUF * msg_ptr_i)
2107 {
2108 UBYTE result;
2109 UBYTE msg_type = msg_ptr_i->buf[0] >> 2;;
2110
2111 TRACE_FUNCTION( "grlc_decode_grlc" );
2112
2113 /*
2114 * Offset must be zero, else code to get msg_type is illegal
2115 */
2116 TRACE_ASSERT (msg_ptr_i->o_buf==0);
2117
2118
2119
2120 switch (msg_type)
2121 {
2122 case D_UL_ACK:
2123 if(!grlc_data->grlc_wo_ccd)
2124 {
2125 result = ccd_decodeMsg (CCDENT_GRLC, DOWNLINK, msg_ptr_i, _decodedMsg, NOT_PRESENT_8BIT);
2126 }
2127 else
2128 {
2129 result = grlc_decode_ul_acknack(msg_ptr_i->buf);
2130 }
2131 break;
2132 default:
2133 TRACE_ERROR(" not Packet ul ack decoded: should nor happen ");
2134 result = DELETE_MESSAGE;
2135 break;
2136 }
2137
2138
2139 if ( result EQ ccdError )
2140 {
2141 return grlc_ccd_error_handling( CCDENT_GRLC );
2142 }
2143
2144 return msg_type;
2145
2146 } /* grlc_decode_grlc() */
2147
2148
2149
2150 /*
2151 +------------------------------------------------------------------------------
2152 | Function : grlc_activate_tfi
2153 +------------------------------------------------------------------------------
2154 | Description :
2155 | grlc_activate_tfi modifies tfi´s if tbf starting time is reached
2156 |
2157 |
2158 | Parameters : fn_i is the current framenuber in tbf mode
2159 |
2160 +------------------------------------------------------------------------------
2161 */
2162
2163 GLOBAL void grlc_activate_tfi (ULONG fn_i)
2164 {
2165
2166 TRACE_FUNCTION( "grlc_activate_tfi" );
2167
2168
2169 /* 1. check if starting time is reached */
2170 switch(grlc_data->tfi_change)
2171 {
2172 case TFI_CHANGE_UL:
2173 if(grlc_check_if_tbf_start_is_elapsed ( grlc_data->ul_tbf_start_time, ((fn_i+5)%FN_MAX)))
2174 {
2175 grlc_data->tfi_change = TFI_CHANGE_NULL;
2176 grlc_data->ul_tfi = grlc_data->start_fn_ul_tfi;
2177 grlc_data->start_fn_ul_tfi = 0xFF;
2178 TRACE_EVENT_P2("UL TFI CHANGE St reached st_fn=%ld c_fn=%ld",grlc_data->ul_tbf_start_time,fn_i );
2179 grlc_data->ul_tbf_start_time = CGRLC_STARTING_TIME_NOT_PRESENT;
2180 grlc_data->tbf_ctrl[grlc_data->ul_index].tfi = grlc_data->ul_tfi;
2181 grlc_data->ul_tfi_changed = TRUE;
2182 }
2183 break;
2184 case TFI_CHANGE_DL:
2185 if(grlc_check_if_tbf_start_is_elapsed ( grlc_data->dl_tbf_start_time, fn_i))
2186 {
2187 grlc_data->tfi_change = TFI_CHANGE_NULL;
2188 grlc_data->dl_tfi = grlc_data->start_fn_dl_tfi;
2189 grlc_data->start_fn_dl_tfi = 0xFF;
2190 TRACE_EVENT_P2("DL TFI CHANGE St reached st_fn=%ld c_fn=%ld",grlc_data->dl_tbf_start_time,fn_i );
2191 grlc_data->dl_tbf_start_time = CGRLC_STARTING_TIME_NOT_PRESENT;
2192 grlc_data->tbf_ctrl[grlc_data->dl_index].tfi = grlc_data->dl_tfi;
2193 }
2194 break;
2195 case TFI_CHANGE_ALL:
2196 if(grlc_check_if_tbf_start_is_elapsed ( grlc_data->ul_tbf_start_time, ((fn_i+5)%FN_MAX)))
2197 {
2198 grlc_data->tfi_change = TFI_CHANGE_DL;
2199 grlc_data->ul_tfi = grlc_data->start_fn_ul_tfi;
2200 grlc_data->start_fn_ul_tfi = 0xFF;
2201 TRACE_EVENT_P2("UL TFI CHANGE(ALL) St reached st_fn=%ld c_fn=%ld",grlc_data->ul_tbf_start_time,fn_i );
2202 grlc_data->ul_tbf_start_time = CGRLC_STARTING_TIME_NOT_PRESENT;
2203 grlc_data->tbf_ctrl[grlc_data->ul_index].tfi = grlc_data->ul_tfi;
2204 grlc_data->tbf_ctrl[grlc_data->dl_index].tfi = grlc_data->dl_tfi;
2205 grlc_data->ul_tfi_changed = TRUE;
2206 }
2207 if(grlc_check_if_tbf_start_is_elapsed ( grlc_data->dl_tbf_start_time, fn_i))
2208 {
2209 if (grlc_data->tfi_change EQ TFI_CHANGE_DL)
2210 grlc_data->tfi_change = TFI_CHANGE_NULL;
2211 else
2212 grlc_data->tfi_change = TFI_CHANGE_UL;
2213 grlc_data->dl_tfi = grlc_data->start_fn_dl_tfi;
2214 grlc_data->start_fn_dl_tfi = 0xFF;
2215 TRACE_EVENT_P2("DL TFI CHANGE(ALL) St reached st_fn=%ld c_fn=%ld",grlc_data->dl_tbf_start_time,fn_i );
2216 grlc_data->dl_tbf_start_time = CGRLC_STARTING_TIME_NOT_PRESENT;
2217 }
2218 break;
2219 }
2220 }
2221
2222 /*
2223 +------------------------------------------------------------------------------
2224 | Function : grlc_t_status
2225 +------------------------------------------------------------------------------
2226 | Description : This function returns the remaining time in milliseconds.
2227 | A value of 0L is returned in case the timer is not existing or
2228 | not running.
2229 |
2230 | Parameters : t_index : timer index
2231 |
2232 +------------------------------------------------------------------------------
2233 */
2234 GLOBAL T_TIME grlc_t_status( USHORT t_index )
2235 {
2236 T_TIME t_time = 0L;
2237
2238 TRACE_FUNCTION( "grlc_t_status" );
2239
2240 vsi_t_status( GRLC_handle, t_index, &t_time );
2241
2242 return( t_time );
2243 } /* grlc_t_status */
2244
2245 /*
2246 +------------------------------------------------------------------------------
2247 | Function : grlc_enter_standby_state
2248 +------------------------------------------------------------------------------
2249 | Description : This function is called in case the STANDBY state should be
2250 | entered.
2251 |
2252 | Parameters :
2253 |
2254 +------------------------------------------------------------------------------
2255 */
2256 GLOBAL void grlc_enter_standby_state ( void )
2257 {
2258 TRACE_FUNCTION( "grlc_enter_standby_state" );
2259
2260 if( grlc_data->ready_timer.handling EQ READY_TIMER_HANDLING_ENABLED )
2261 {
2262 if( grlc_data->ready_timer.state EQ READY_STATE )
2263 {
2264 /* The ready_timer.state is set to STANDBY_STATE just in case we are not already in this state.
2265 The CGRLC_STANDBY_STATE_IND primitives are sent if we move from READY_STATE to STANDBY_STATE only.
2266 */
2267 if( grlc_data->ready_timer.value NEQ CGRLC_DEACTIVATED )
2268 {
2269 /* If the timer T3314 expires while we are in READY_STATE but the timer is deactivated then
2270 the transition to STANDBY_STATE will never occur
2271 */
2272 /* If the primitive CGRLC_FORCE_TO_STANDBY_REQ is received when we are in Ready State but
2273 the timer is deactivated then the transition to STANDBY_STATE will never occur
2274 */
2275 grlc_data->ready_timer.state = STANDBY_STATE;
2276 vsi_t_stop( GRLC_handle, T3314 );
2277
2278 {
2279 PALLOC(cgrlc_standby_state_ind,CGRLC_STANDBY_STATE_IND); /* T_CGRLC_STANDBY_STATE_IND sent to GMM */
2280 PSEND(hCommGMM,cgrlc_standby_state_ind);
2281 }
2282
2283 {
2284 PALLOC(cgrlc_standby_state_ind,CGRLC_STANDBY_STATE_IND); /* T_CGRLC_STANDBY_STATE_IND sent to GRR */
2285 PSEND(hCommGRR,cgrlc_standby_state_ind);
2286 }
2287 }
2288 else
2289 {
2290 TRACE_EVENT( "grlc_enter_standby_state: MS enters STANDBY state while T3314 is deactivated" );
2291 }
2292 }
2293 else
2294 {
2295 TRACE_EVENT( "grlc_enter_standby_state: MS is already in STANDBY state" );
2296 }
2297 }
2298 } /* grlc_enter_standby_state */
2299
2300 /*
2301 +------------------------------------------------------------------------------
2302 | Function : grlc_enter_ready_state
2303 +------------------------------------------------------------------------------
2304 | Description : This function is called in case the READY state should be
2305 | entered.
2306 |
2307 | Parameters :
2308 |
2309 +------------------------------------------------------------------------------
2310 */
2311 GLOBAL void grlc_enter_ready_state ( void )
2312 {
2313 TRACE_FUNCTION( "grlc_enter_ready_state" );
2314
2315 if (grlc_data->ready_timer.state EQ STANDBY_STATE)
2316 {
2317 /* The ready_timer.state is set to READY_STATE just in case we are not already in this state.
2318 The CGRLC_READY_STATE_IND primitives are sent only if we move from STANDBY_STATE to READY_STATE */
2319
2320 /* If we receive the primitive CGRLC_READY_TIMER_CONFIG_REQ with timer value CGRLC_DEACTIVATED when
2321 we are in CGRLC_STANDBY, the state will immediately switch to READY and the CGRLC_READY_STATE_IND
2322 primitives will be sent */
2323 grlc_data->ready_timer.state = READY_STATE;
2324
2325 {
2326 PALLOC(cgrlc_ready_state_ind,CGRLC_READY_STATE_IND); /* T_CGRLC_READY_STATE_IND sent to GMM */
2327 PSEND(hCommGMM,cgrlc_ready_state_ind);
2328 }
2329
2330 {
2331 PALLOC(cgrlc_ready_state_ind,CGRLC_READY_STATE_IND); /* T_CGRLC_READY_STATE_IND sent to GRR */
2332 PSEND(hCommGRR,cgrlc_ready_state_ind);
2333 }
2334 }
2335 else
2336 {
2337 TRACE_EVENT( "grlc_enter_ready_state: MS is already in READY state" );
2338 }
2339 } /* grlc_enter_ready_state */
2340 /*
2341 +------------------------------------------------------------------------------
2342 | Function : grlc_convert_11bit_2_etsi
2343 +------------------------------------------------------------------------------
2344 | Description : Converts the 11 bit access burst value into ETSI format
2345 |
2346 | Parameters : In: eleven bit value
2347 | Out: converted eleven bit
2348 |
2349 +------------------------------------------------------------------------------
2350 */
2351 LOCAL USHORT grlc_convert_11bit_2_etsi ( USHORT eleven_bit )
2352 {
2353 USHORT etsi11bit;
2354 USHORT dummy1 = 0, dummy2 = 0;
2355
2356 TRACE_FUNCTION( "grlc_convert_11bit_2_etsi" );
2357
2358 /*
2359 * 11 Bit access burst
2360 * b: bit
2361 * b10 b9 b8 b7 b6 b5 b4 b3 b2 b1 b0
2362 * should be sent to the network -according 04.60 and 0404- in the
2363 * following 16-bit format:
2364 * 0 0 0 0 0 b2 b1 b0 b10 b9 b8 b7 b6 b5 b4 b3
2365 */
2366
2367 /*
2368 * get b2 b1 b0
2369 */
2370 dummy1 = 0x0007 & eleven_bit;
2371
2372 /*
2373 * shift it 8 bits to left
2374 */
2375 dummy1 = ( dummy1 << 8 );
2376
2377 /*
2378 * get b10 b9 b8 b7 b6 b5 b4 b3
2379 */
2380 dummy2 = 0xFFF8 & eleven_bit;
2381
2382 /*
2383 * shift it 3 bits to right
2384 */
2385 dummy2 = ( dummy2 >> 3 );
2386
2387 /*
2388 * compose dummy1 and dummy2 to the target 16-bit format
2389 */
2390 etsi11bit = dummy1 | dummy2;
2391
2392 return etsi11bit;
2393
2394 } /* grlc_convert_11bit_2_etsi() */