comparison src/g23m-gprs/llc/llc_rxp.c @ 1:d393cd9bb723

src/g23m-*: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:40:46 +0000
parents
children
comparison
equal deleted inserted replaced
0:b6a5e36de839 1:d393cd9bb723
1 /*
2 +-----------------------------------------------------------------------------
3 | Project :
4 | Modul :
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 modul is part of the entity LLC and implements all
18 | functions to handles the incoming primitives as described in
19 | the SDL-documentation (RX-statemachine)
20 +-----------------------------------------------------------------------------
21 */
22
23 #ifndef LLC_RXP_C
24 #define LLC_RXP_C
25 #endif
26
27 #define ENTITY_LLC
28
29 /*==== INCLUDES =============================================================*/
30
31 #include "typedefs.h" /* to get Condat data types */
32 #include "vsi.h" /* to get a lot of macros */
33 #include "macdef.h"
34 #include "gprs.h"
35 #include "gsm.h" /* to get a lot of macros */
36 #include "cnf_llc.h" /* to get cnf-definitions */
37 #include "mon_llc.h" /* to get mon-definitions */
38 #include "prim.h" /* to get the definitions of used SAP and directions */
39 #include "llc.h" /* to get the global entity definitions */
40
41 #include "llc_rxf.h" /* to get local RX functions */
42 #include "llc_us.h" /* to get signal interface to U */
43 #include "llc_uirxs.h" /* to get signal interface to UIRX */
44 #include "llc_irxs.h" /* to get signal interface to IRX */
45
46 #ifdef _SIMULATION_
47 #include <string.h> /* to get memcpy() */
48 #endif
49
50 /*==== CONST ================================================================*/
51
52 /*==== LOCAL VARS ===========================================================*/
53
54 /*==== PRIVATE FUNCTIONS ====================================================*/
55
56 #ifdef _SIMULATION_
57 LOCAL void rx_copy_test_primitive_data (T_GRLC_UNITDATA_IND_TEST
58 *grlc_unitdata_ind_test,
59 T_GRLC_UNITDATA_IND *grlc_unitdata_ind);
60 #endif
61
62 #ifndef CF_FAST_EXEC
63
64 GLOBAL void rx_grlc_xdata_ind (T_GRLC_UNITDATA_IND *grlc_unitdata_ind);
65
66 #endif /* CF_FAST_EXEC */
67
68
69 /*==== PUBLIC FUNCTIONS =====================================================*/
70
71
72 /*
73 +------------------------------------------------------------------------------
74 | Function : rx_grlc_data_ind
75 +------------------------------------------------------------------------------
76 | Description : Handles the primitive GRLC_DATA_IND
77 |
78 | Parameters : *grlc_data_ind - Ptr to primitive payload
79 |
80 +------------------------------------------------------------------------------
81 */
82 #ifndef CF_FAST_EXEC
83
84 GLOBAL void rx_grlc_data_ind ( T_GRLC_DATA_IND *grlc_data_ind )
85 {
86 TRACE_FUNCTION( "grlc_data_ind" );
87
88 switch( GET_STATE( RX ) )
89 {
90 case RX_TLLI_ASSIGNED:
91 {
92 /*
93 * Both primitives are treated the same way and contain the same
94 * information.
95 */
96 PPASS (grlc_data_ind, grlc_unitdata_ind, GRLC_UNITDATA_IND);
97
98 /*
99 * Primitive is handled in rx_grlc_xdata_ind().
100 */
101 rx_grlc_xdata_ind (grlc_unitdata_ind);
102 break;
103 }
104 default:
105 PFREE_DESC (grlc_data_ind);
106 TRACE_ERROR( "GRLC_DATA_IND unexpected" );
107 break;
108 }
109
110 } /* rx_grlc_data_ind() */
111
112 #endif /* CF_FAST_EXEC */
113
114
115 /*
116 +------------------------------------------------------------------------------
117 | Function : rx_grlc_unitdata_ind
118 +------------------------------------------------------------------------------
119 | Description : Handles the primitive GRLC_UNITDATA_IND
120 |
121 | Parameters : *grlc_unitdata_ind - Ptr to primitive payload
122 |
123 +------------------------------------------------------------------------------
124 */
125 #ifndef CF_FAST_EXEC
126
127 GLOBAL void rx_grlc_unitdata_ind ( T_GRLC_UNITDATA_IND *grlc_unitdata_ind )
128 {
129 TRACE_FUNCTION( "grlc_unitdata_ind" );
130
131 switch( GET_STATE( RX ) )
132 {
133 case RX_TLLI_ASSIGNED:
134 /*
135 * Primitive is handled in rx_grlc_xdata_ind().
136 */
137 rx_grlc_xdata_ind (grlc_unitdata_ind);
138 break;
139 default:
140 PFREE_DESC (grlc_unitdata_ind);
141 TRACE_ERROR( "GRLC_UNITDATA_IND unexpected" );
142 break;
143 }
144
145 } /* rx_grlc_unitdata_ind() */
146
147 #endif /* CF_FAST_EXEC */
148
149
150 /*
151 +------------------------------------------------------------------------------
152 | Function : rx_cci_decipher_cnf
153 +------------------------------------------------------------------------------
154 | Description : Handles the primitive CCI_DECIPHER_CNF.
155 | Note: The type LL_UNITDATA_IND is used instead to avoid PPASS
156 .
157 |
158 | Parameters : *ll_unitdata_ind - Ptr to primitive payload
159 |
160 +------------------------------------------------------------------------------
161 */
162 /*#if defined(CF_FAST_EXEC) || defined(_SIMULATION_) || \
163 defined(LL_2to1) */
164
165 GLOBAL void rx_cci_decipher_cnf ( T_LL_UNITDATA_IND *ll_unitdata_ind)
166 {
167 UBYTE cipher;
168 T_PDU_TYPE frame_type;
169 T_COMMAND command;
170 T_BIT cr_bit;
171 T_BIT pf_bit;
172 T_FRAME_NUM nr;
173 T_FRAME_NUM ns;
174 BOOL frame_ok;
175 UBYTE frame_rej;
176 USHORT frame_rej_ctrl_length;
177 USHORT ctrl_len;
178
179
180 TRACE_FUNCTION( "rx_cci_decipher_cnf" );
181
182 cipher = ll_unitdata_ind->cipher;
183
184 switch( GET_STATE( RX ) )
185 {
186 case RX_TLLI_ASSIGNED:
187 /* variable sapi is "misused" for fcs_check value */
188 if (ll_unitdata_ind->sapi EQ CCI_FCS_PASSED)
189 {
190
191 {
192 /*
193 * Label INTERPRET
194 */
195
196 rx_interpret_frame (&ll_unitdata_ind->sdu, &ll_unitdata_ind->sapi,
197 &frame_type, &command, &cr_bit, &pf_bit, &nr, &ns, &frame_ok,
198 &frame_rej, &frame_rej_ctrl_length, cipher);
199
200 SWITCH_LLC (ll_unitdata_ind->sapi);
201
202 /*
203 * In case of I-frames check, if the information field exceeds N201-I
204 */
205 if (frame_type == I_FRAME)
206 {
207 ctrl_len = I_CTRL_MIN_OCTETS;
208
209 /*
210 * Add sizeof SACK-Bitmap, if necessarry (add K+1)
211 */
212 if (command == I_SACK)
213 {
214 ctrl_len += (ll_unitdata_ind->sdu.buf[(ll_unitdata_ind->sdu.o_buf/8)+4]
215 & 0x1F) + 1;
216 }
217
218 if (BYTELEN(ll_unitdata_ind->sdu.l_buf) > *(llc_data->n201_i) + ctrl_len)
219 {
220 frame_ok = FALSE;
221 frame_rej = FRMR_W2;
222
223 TRACE_0_INFO("Received frame violates N201-I: send FRMR");
224 }
225 }
226
227 /*
228 * frame_ok includes: correct frame length, PD bit == 0, SAPI valid,
229 * FCS correct, known PDU type.
230 */
231 if (frame_ok EQ TRUE)
232 {
233 rx_strip_llc_header (&ll_unitdata_ind->sdu, frame_type, command);
234
235 /*
236 * Label S_DATA
237 */
238
239 switch (frame_type)
240 {
241 case U_FRAME:
242 /*
243 * Label U_FRAME
244 */
245
246 /*
247 * Service u_frames receives the SDU within the allocated UNITDATA
248 * primitive.
249 */
250 sig_rx_u_data_ind (ll_unitdata_ind, command, cr_bit, pf_bit);
251 break;
252 case UI_FRAME:
253 /*
254 * Label UI_FRAME
255 */
256
257 sig_rx_uirx_data_ind (ll_unitdata_ind, nr);
258 break;
259 case S_FRAME:
260 /*
261 * No break. S frames and I frames are treated the same way.
262 */
263 case I_FRAME:
264 /*
265 * Label I_FRAME
266 */
267
268 sig_rx_irx_data_ind (ll_unitdata_ind,
269 command, frame_type, cr_bit, pf_bit, ns, nr);
270 break;
271 default:
272 PFREE (ll_unitdata_ind);
273 TRACE_ERROR ("unknown frame type");
274 break;
275 }
276 }
277 else /* frame_ok EQ FALSE */
278 {
279 /*
280 * Check if frame rejection condition occurred, and if U has to be
281 * informed.
282 */
283 if (frame_rej EQ FRAME_NOT_REJ)
284 {
285 TRACE_0_INFO("Frame ignored due to decode problem");
286 PFREE (ll_unitdata_ind);
287 }
288 else /* W1 bit and/or W3 bit set */
289 {
290 /*
291 * Inform U of the frame rejection condition.
292 */
293 TRACE_0_INFO("Frame rejected due to decode problem");
294 sig_rx_u_frmr_ind (ll_unitdata_ind, frame_type, frame_rej_ctrl_length,
295 cr_bit, frame_rej);
296 }
297 }
298 } /* end of validity range of ll_unitdata_ind */
299 }
300 else /* fcs_check EQ CCI_FCS_FAILED */
301 {
302 #ifdef TRACE_EVE
303 UBYTE sapi;
304
305 rx_interpret_frame (&ll_unitdata_ind->sdu, &sapi,
306 &frame_type, &command, &cr_bit, &pf_bit, &nr, &ns, &frame_ok,
307 &frame_rej, &frame_rej_ctrl_length, cipher);
308 #endif
309 TRACE_0_INFO("Frame discarded due to FCS");
310 PFREE (ll_unitdata_ind);
311 }
312 break;
313 default:
314 PFREE(ll_unitdata_ind);
315 TRACE_ERROR( "CCI_DECIPHER_CNF unexpected" );
316 break;
317 }
318
319 } /* rx_cci_decipher_cnf() */
320
321 /*#endif */ /* CF_FAST_EXEC || _SIMULATION_ */
322
323
324 /*
325 +------------------------------------------------------------------------------
326 | Function : rx_grlc_data_ind_test
327 +------------------------------------------------------------------------------
328 | Description : Handles the primitive GRLC_DATA_IND_TEST
329 | NOTE: This is only necessary in simulation environment.
330 |
331 | Parameters : *grlc_data_ind_test - Ptr to primitive payload
332 |
333 +------------------------------------------------------------------------------
334 */
335 #ifdef _SIMULATION_
336 GLOBAL void rx_grlc_data_ind_test ( T_GRLC_DATA_IND_TEST *grlc_data_ind_test )
337 {
338 TRACE_FUNCTION( "grlc_data_ind_test" );
339
340 switch( GET_STATE( RX ) )
341 {
342 case RX_TLLI_ASSIGNED:
343 {
344 /*
345 * Allocate a "normal" GRLC_UNITDATA_IND primitive and copy the data
346 * of the test primitive GRLC_DATA_IND_TEST (sdu) to
347 * GRLC_UNITDATA_IND (desc_list).
348 */
349 PALLOC_DESC (grlc_unitdata_ind, GRLC_UNITDATA_IND);
350
351 grlc_unitdata_ind->tlli = grlc_data_ind_test->tlli;
352 rx_copy_test_primitive_data ((T_GRLC_UNITDATA_IND_TEST *)grlc_data_ind_test,
353 grlc_unitdata_ind);
354
355 /*
356 * Free the received test primitive.
357 */
358 PFREE (grlc_data_ind_test);
359
360 /*
361 * Primitive is handled in rx_grlc_xdata_ind().
362 */
363 rx_grlc_xdata_ind (grlc_unitdata_ind);
364 break;
365 }
366 default:
367 PFREE (grlc_data_ind_test);
368 TRACE_ERROR( "GRLC_DATA_IND_TEST unexpected" );
369 break;
370 }
371
372 } /* rx_grlc_data_ind_test() */
373 #endif /* _SIMULATION_ */
374
375
376 /*
377 +------------------------------------------------------------------------------
378 | Function : rx_grlc_unitdata_ind_test
379 +------------------------------------------------------------------------------
380 | Description : Handles the primitive GRLC_UNITDATA_IND_TEST
381 | NOTE: This is only necessary in simulation environment.
382 |
383 | Parameters : *grlc_unitdata_ind_test - Ptr to primitive payload
384 |
385 +------------------------------------------------------------------------------
386 */
387 #ifdef _SIMULATION_
388 GLOBAL void rx_grlc_unitdata_ind_test ( T_GRLC_UNITDATA_IND_TEST
389 *grlc_unitdata_ind_test )
390 {
391 TRACE_FUNCTION( "grlc_unitdata_ind_test" );
392
393 switch( GET_STATE( RX ) )
394 {
395 case RX_TLLI_ASSIGNED:
396 {
397 /*
398 * Allocate a "normal" GRLC_UNITDATA_IND primitive and copy the data
399 * of the test primitive GRLC_UNITDATA_IND_TEST (sdu) to
400 * GRLC_UNITDATA_IND (desc_list).
401 */
402 PALLOC_DESC (grlc_unitdata_ind, GRLC_UNITDATA_IND);
403
404 grlc_unitdata_ind->tlli = grlc_unitdata_ind_test->tlli;
405 rx_copy_test_primitive_data (grlc_unitdata_ind_test, grlc_unitdata_ind);
406
407 /*
408 * Free the received test primitive.
409 */
410 PFREE (grlc_unitdata_ind_test);
411
412 /*
413 * Primitive is handled in rx_grlc_xdata_ind().
414 */
415 rx_grlc_xdata_ind (grlc_unitdata_ind);
416 break;
417 }
418 default:
419 PFREE (grlc_unitdata_ind_test);
420 TRACE_ERROR( "GRLC_UNITDATA_IND_TEST unexpected" );
421 break;
422 }
423
424 } /* rx_grlc_unitdata_ind_test() */
425 #endif /* _SIMULATION_ */
426
427
428 /*
429 +------------------------------------------------------------------------------
430 | Function : rx_copy_test_primitive_data
431 +------------------------------------------------------------------------------
432 | Description : Copies the data of a TEST primitive (sdu) to a normal
433 | primitive (desc_list).
434 | ATTENTION: All other parameters of the primitives are left
435 | untouched and are not copied by this function!
436 |
437 | Parameters : *grlc_unitdata_ind_test - source primitive
438 | *grlc_unitdata_ind - destination primitive
439 |
440 +------------------------------------------------------------------------------
441 */
442 #ifdef _SIMULATION_
443 LOCAL void rx_copy_test_primitive_data (T_GRLC_UNITDATA_IND_TEST
444 *grlc_unitdata_ind_test,
445 T_GRLC_UNITDATA_IND *grlc_unitdata_ind)
446 {
447 #define FRAG_LEN 80 /* value + 6 must fit in an pool with lots of entries */
448
449 T_sdu *sdu;
450 T_desc *desc;
451 T_desc *last_desc = NULL;
452 int sdu_index;
453 int length;
454
455
456 sdu = &grlc_unitdata_ind_test->sdu;
457
458 /*
459 * Begin at the first relevant octet.
460 */
461 sdu_index = sdu->o_buf/8;
462
463 /*
464 * Initialise descriptor list length.
465 */
466 grlc_unitdata_ind->desc_list.list_len = 0;
467
468
469 /*
470 * Copy complete SDU to descriptor list using descriptors of max. 10 bytes.
471 */
472 while (sdu_index < sdu->l_buf/8)
473 {
474 /*
475 * Calculate length of descriptor data (= length of remaining sdu buffer
476 * with a maximum of FRAG_LEN)
477 */
478 length = (sdu_index+FRAG_LEN < sdu->l_buf/8) ? FRAG_LEN
479 : (sdu->l_buf/8 - sdu_index);
480
481 /*
482 * Allocate the necessary size for the data descriptor. The size is
483 * calculated as follows:
484 * - take the size of a descriptor structure
485 * - subtract one because of the array buffer[1] to get the size of
486 * descriptor control information
487 * - add number of octets of descriptor data
488 */
489 MALLOC (desc, (USHORT)(sizeof(T_desc) - 1 + length));
490
491 /*
492 * Fill descriptor control information.
493 */
494 desc->next = (ULONG)NULL;
495 desc->len = length;
496
497 /*
498 * Add length of descriptor data to list length.
499 */
500 grlc_unitdata_ind->desc_list.list_len += length;
501
502 /*
503 * Copy user data from SDU to descriptor.
504 */
505 memcpy (desc->buffer, &sdu->buf[sdu_index], length);
506 sdu_index += length;
507
508 if (last_desc)
509 {
510 /*
511 * Add this descriptor (not the first) to the descriptor list.
512 */
513 last_desc->next = (ULONG)desc;
514 }
515 else
516 {
517 /*
518 * Insert first descriptor in descriptor list.
519 */
520 grlc_unitdata_ind->desc_list.first = (ULONG)desc;
521 }
522
523 /*
524 * Store this descriptor for later use.
525 */
526 last_desc = desc;
527 }
528
529 return;
530 } /* rx_copy_test_primitive_data */
531 #endif /* _SIMULATION_ */
532
533
534 /*
535 +------------------------------------------------------------------------------
536 | Function : rx_grlc_xdata_ind
537 +------------------------------------------------------------------------------
538 | Description : Handles the primitives GRLC_DATA_IND / GRLC_UNITDATA_IND.
539 |
540 | Parameters : *grlc_unitdata_ind - Ptr to primitive payload
541 |
542 +------------------------------------------------------------------------------
543 */
544 #ifndef CF_FAST_EXEC
545
546 GLOBAL void rx_grlc_xdata_ind ( T_GRLC_UNITDATA_IND *grlc_unitdata_ind )
547 {
548 T_PDU_TYPE frame_type;
549 UBYTE protected_mode;
550 UBYTE sapi;
551 T_FRAME_NUM ns;
552 BOOL ciphering;
553 USHORT header_size;
554 BOOL frame_ok;
555
556
557 TRACE_FUNCTION( "grlc_xdata_ind" );
558
559 /*
560 * Unassigning old TLLI
561 *
562 * GMM has to be informed, that new TLLI has been received. So GMM can unassign old TLLI
563 * and old PTMSI in GRLC
564 * Old tlli will be unassigned here. Normally GMM has to sent LLGMM_ASSIGN_REQ with
565 * new_tlli != all 1's and old_tlli == all 1,s. See 04.64 cp. 6.1 <R.LLC.TLLI_ASS.A.002>
566 */
567 #ifdef LL_2to1
568 if ( PS_TLLI_INVALID != llc_data->tlli_old
569 #else
570 if ( LLGMM_TLLI_INVALID != llc_data->tlli_old
571 #endif
572 && grlc_unitdata_ind->tlli != llc_data->tlli_old )
573 {
574 PALLOC ( llgmm_tlli_ind, LLGMM_TLLI_IND );
575 llgmm_tlli_ind->new_tlli = grlc_unitdata_ind->tlli;
576 #ifdef LL_2to1
577 llc_data->tlli_old = PS_TLLI_INVALID;
578 #else
579 llc_data->tlli_old = LLGMM_TLLI_INVALID;
580 #endif
581 PSEND ( hCommGMM, llgmm_tlli_ind);
582 }
583 rx_analyse_ctrl_field (grlc_unitdata_ind, &frame_type, &protected_mode,
584 &sapi, &ns, &ciphering, &header_size, &frame_ok);
585
586 if (frame_ok EQ TRUE)
587 {
588 /*
589 * Check, if the sapi of the frame is supported. If ok, switch context
590 * and handle the frame.
591 */
592 switch (sapi)
593 {
594 case LL_SAPI_1:
595 case LL_SAPI_3:
596 case LL_SAPI_5:
597 case LL_SAPI_7:
598 case LL_SAPI_9:
599 case LL_SAPI_11:
600 SWITCH_LLC (sapi);
601 rx_send_decipher_req (grlc_unitdata_ind, frame_type, protected_mode,
602 ns, header_size, ciphering);
603 /*
604 * Free only the primitive (desc_list copied in rx_send_decipher_req)
605 */
606 PFREE (grlc_unitdata_ind); /* Do not use PFREE_DESC here !*/
607 break;
608
609 default:
610 /*
611 * Ignore frame.
612 * Free prim and desc_list, because they are not used further
613 */
614 PFREE_DESC (grlc_unitdata_ind);
615 TRACE_0_INFO("Frame received for reserved SAPI");
616 break;
617 }
618 }
619 else /* frame_ok NEQ TRUE */
620 {
621 /*
622 * Free GRLC_UNITDATA_IND along with complete descriptor list.
623 */
624 PFREE_DESC (grlc_unitdata_ind);
625 TRACE_EVENT("Frame ignored!");
626 }
627
628 return;
629 } /* rx_grlc_xdata_ind() */
630
631 #endif /* CF_FAST_EXEC */
632