comparison src/g23m-gprs/llc/llc_ul.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 :
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 labels
18 | in the SDL-documentation (U-statemachine) that are called from
19 | more than one diagram/place.
20 +-----------------------------------------------------------------------------
21 */
22
23 #ifndef LLC_UL_C
24 #define LLC_UL_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_uf.h" /* to get local U functions */
42 #include "llc_ul.h" /* to get local U labels */
43 #include "llc_llmes.h" /* to get signal interface to LLME */
44 #include "llc_t200s.h" /* to get signal interface to T200 */
45 #include "llc_txs.h" /* to get signal interface to TX */
46
47 /*==== CONST ================================================================*/
48
49 /*==== LOCAL VARS ===========================================================*/
50
51 /*==== PRIVATE FUNCTIONS ====================================================*/
52
53 /*==== PUBLIC FUNCTIONS =====================================================*/
54
55
56
57 /*
58 +------------------------------------------------------------------------------
59 | Function : u_handle_mX_zero_rsp
60 +------------------------------------------------------------------------------
61 | Description : This function handles the XID response in case we want to set
62 | mX to zero and the peer does not.
63 |
64 | Parameters : mX_req - requested value of mD or mU
65 | n201_i - ptr to current n201_i
66 | mX - ptr to current (=received) mD or current mU
67 | kX - ptr to current kD or current kU
68 | kX_min - minimum value of kD or kU
69 | kX_max - maximum value of kD or kU
70 | kX_type - XID_KU or XID_KD
71 +------------------------------------------------------------------------------
72 */
73 GLOBAL void u_handle_mX_zero_rsp (USHORT mX_req, USHORT* n201_i,
74 USHORT mX, USHORT mX_max,
75 UBYTE* kX, UBYTE kX_min,
76 UBYTE kX_type )
77 {
78 TRACE_FUNCTION( "u_handle_mX_zero_rsp" );
79
80 /*
81 * calc new N201-I and/or kX, if necessary
82 */
83 #if XID_N201_I_MIN != 0u /* avoid division with 0 */
84 if ( (mX_max == 0u) AND (mX_req != 0u) AND (*kX * mX > mX_req) )
85 {
86 /*
87 * first try to reduce n201-I only, else reduce also k
88 * Note: *kX can't be 0 here
89 */
90 if ( *kX * XID_N201_I_MIN <= mX_req * 16u )
91 {
92 /*
93 * calc and tag N201-I
94 */
95 *n201_i = (mX_req * 16u) / *kX;
96
97 llc_data->u->xid_tag |= (0x00000001L << XID_N201_I);
98
99 }
100 else if ( kX_min * XID_N201_I_MIN <= mX_req * 16u )
101 {
102 /*
103 * calc and tag N201-I and kX
104 */
105 *n201_i = XID_N201_I_MIN;
106 *kX = (mX_req * 16u) / XID_N201_I_MIN;
107
108 llc_data->u->xid_tag |= (0x00000001L << XID_N201_I);
109 llc_data->u->xid_tag |= (0x00000001L << kX_type);
110 }
111 else
112 {
113 TRACE_ERROR("Requested value of mX is too small");
114 }
115 }
116 #endif /* XID_N201_I_MIN != 0u */
117 } /* u_handle_mX_zero_rsp() */
118
119
120 /*
121 +------------------------------------------------------------------------------
122 | Function : u_label_xid
123 +------------------------------------------------------------------------------
124 | Description : Describes label XID
125 |
126 | Parameters : ll_unitdata_ind - a valid pointer to an LL_UNITDATA_IND
127 | primitive
128 | command - contains command of primitive
129 | cr_bit - setting of C/R bit
130 | pf_bit - setting of P/F bit
131 |
132 +------------------------------------------------------------------------------
133 */
134 GLOBAL void u_label_xid (T_LL_UNITDATA_IND *ll_unitdata_ind,
135 T_COMMAND command,
136 T_BIT cr_bit,
137 T_BIT pf_bit)
138 {
139 BOOL reset_received;
140 BOOL xid_ind;
141
142
143 TRACE_FUNCTION( "u_label_xid" );
144
145 if (pf_bit EQ 1)
146 {
147 /*
148 * Check XID parameters and store the decoded values in
149 * llc_data->decoded_xid.
150 */
151 if (u_check_xid (&ll_unitdata_ind->sdu, cr_bit, command))
152 {
153 /*
154 * In case of reset, all incarnations in ABM are set to ADM
155 * by u_eval_xid()!
156 */
157 u_eval_xid (cr_bit, &reset_received, &xid_ind);
158
159 if (llc_data->u->xid_pending)
160 {
161 /*
162 * We have an XID command collision!
163 */
164
165 if ( (llc_data->decoded_l3_xid.valid EQ TRUE) AND
166 !(llc_data->u->xid_tag_sent & (0x00000001L << XID_LAYER_3)))
167 {
168 /*
169 * Peer XID command contains layer-3 parameters, our XID command
170 * doesn't.
171 */
172 llc_data->u->xid_pending = FALSE;
173
174 sig_u_t200_stop_req();
175
176 /*
177 * Label XID_VALID
178 */
179 u_label_xid_valid (ll_unitdata_ind, reset_received, xid_ind);
180 }
181 else if (reset_received)
182 {
183 /*
184 * An XID command including a valid reset shall not be ignored
185 * and takes precedence over all collision issues
186 */
187 llc_data->u->xid_pending = FALSE;
188
189 sig_u_t200_stop_req();
190
191 /*
192 * Label XID_VALID
193 */
194 u_label_xid_valid (ll_unitdata_ind, reset_received, xid_ind);
195 }
196 else
197 {
198 /*
199 * Layer-3 XID parameters are present in both or neither XID
200 * commands.
201 */
202 PFREE (ll_unitdata_ind);
203 }
204 }
205 else /* xid_pending == FALSE (no XID command sent) */
206 {
207 /*
208 * Label XID_VALID
209 */
210 u_label_xid_valid (ll_unitdata_ind, reset_received, xid_ind);
211 }
212 }
213 else /* u_check_xid() == FALSE (XID invalid) */
214 {
215 PFREE (ll_unitdata_ind);
216 TRACE_0_INFO("invalid XID information field");
217 }
218 }
219 else /* pf_bit == 0 (bit is not set) */
220 {
221 PFREE (ll_unitdata_ind);
222 }
223
224 return;
225 } /* u_label_xid() */
226
227
228 /*
229 +------------------------------------------------------------------------------
230 | Function : u_label_xidres
231 +------------------------------------------------------------------------------
232 | Description : Describes label XIDRES
233 |
234 | Parameters : ll_unitdata_ind - a valid pointer to an LL_UNITDATA_IND
235 | primitive
236 | command - contains command of primitive
237 | cr_bit - setting of C/R bit
238 | pf_bit - setting of P/F bit
239 |
240 +------------------------------------------------------------------------------
241 */
242 GLOBAL void u_label_xidres (T_LL_UNITDATA_IND *ll_unitdata_ind,
243 T_COMMAND command,
244 T_BIT cr_bit,
245 T_BIT pf_bit)
246 {
247 BOOL reset_received;
248 BOOL xid_ind;
249 BOOL l3p_outstanding;
250
251
252 TRACE_FUNCTION( "u_label_xidres" );
253
254 if (pf_bit EQ 1)
255 {
256 /*
257 * Check XID parameters and store the decoded
258 * values in llc_decode_xid
259 */
260 if (u_check_xid (&ll_unitdata_ind->sdu, cr_bit, command))
261 {
262 l3p_outstanding = (llc_data->u->xid_tag_sent & (0x1L << XID_LAYER_3)) ? TRUE : FALSE;
263
264 /*
265 * An XID response frame should only be handled if the XID L3
266 * para are included or not same as requested. Else ignore it!
267 */
268 if (llc_data->decoded_l3_xid.valid == l3p_outstanding)
269 {
270 /*
271 * If an XID parameter is not included in the response and
272 * if it was included in the request, the requested value is
273 * implicit accepted.
274 */
275 u_handle_optimization ();
276
277 /*
278 * Now check XID parameter
279 */
280 u_eval_xid (cr_bit, &reset_received, &xid_ind);
281
282 /*
283 * Label XIDRES_VALID
284 */
285
286 llc_data->u->xid_pending = FALSE;
287
288 sig_u_t200_stop_req ();
289
290 if (l3p_outstanding)
291 {
292 u_send_ll_xid_cnf ();
293 }
294 else
295 {
296 if (xid_ind == TRUE)
297 {
298 u_send_ll_xid_ind ();
299 }
300 }
301
302 PFREE (ll_unitdata_ind);
303 }
304 else
305 {
306 /*
307 * Ignore frame
308 */
309 PFREE (ll_unitdata_ind);
310 }
311 }
312 else
313 {
314 /*
315 * Request T200 to let the timer manually expire.
316 */
317 sig_u_t200_expire_req ();
318 PFREE (ll_unitdata_ind);
319 }
320 }
321 else /* bit is not set */
322 {
323 PFREE (ll_unitdata_ind);
324 }
325 } /* u_label_xidres() */
326
327
328
329 /*
330 +------------------------------------------------------------------------------
331 | Function : u_label_xid_sabm_send
332 +------------------------------------------------------------------------------
333 | Description : Describes label XID_SABM_SEND
334 |
335 | Parameters : ll_unitdata_ind - a valid pointer to an LL_UNITDATA_IND
336 | primitive
337 | cr_bit - setting of C/R bit
338 | pf_bit - setting of P/F bit
339 |
340 +------------------------------------------------------------------------------
341 */
342 GLOBAL void u_label_xid_sabm_send (T_LL_UNITDATA_IND *ll_unitdata_ind,
343 T_BIT cr_bit,
344 T_BIT pf_bit)
345 {
346 BOOL reset_received;
347 BOOL xid_ind;
348
349
350 TRACE_FUNCTION( "u_label_xid_sabm_send" );
351
352 if (pf_bit EQ 1)
353 {
354 /*
355 * Check XID parameters and store the decoded values in
356 * llc_data->decoded_xid.
357 */
358 if (u_check_xid (&ll_unitdata_ind->sdu, cr_bit, U_XID))
359 {
360 /*
361 * We have received an valid XID. If a reset is included
362 * this must be handled even in case of an collision
363 */
364 if (llc_data->decoded_xid.reset.valid)
365 {
366 /*
367 * All incarnations in ABM are set to ADM by u_eval_xid()!
368 */
369 u_eval_xid (cr_bit, &reset_received, &xid_ind);
370
371 /*
372 * Label XID_VALID
373 */
374 u_label_xid_valid (ll_unitdata_ind, reset_received, xid_ind);
375 }
376 else
377 {
378 PFREE (ll_unitdata_ind);
379 }
380 }
381 else /* u_check_xid() == FALSE (XID invalid) */
382 {
383 PFREE (ll_unitdata_ind);
384 TRACE_0_INFO("invalid XID information field");
385 }
386 }
387 else /* pf_bit == 0 (bit is not set) */
388 {
389 PFREE (ll_unitdata_ind);
390 }
391
392 return;
393 } /* u_label_xid_sabm_send() */
394
395
396
397
398 /*
399 +------------------------------------------------------------------------------
400 | Function : u_label_xid_valid
401 +------------------------------------------------------------------------------
402 | Description : Describes label XID_VALID
403 |
404 | Parameters : ll_unitdata_ind - a valid pointer to an LL_UNITDATA_IND
405 | primitive
406 | reset_received - indicates if reset parameter has been
407 | received
408 | xid_ind - indicates if LL_XID_IND must be sent to
409 | layer 3
410 |
411 +------------------------------------------------------------------------------
412 */
413 GLOBAL void u_label_xid_valid (T_LL_UNITDATA_IND *ll_unitdata_ind,
414 BOOL reset_received,
415 BOOL xid_ind)
416 {
417 UBYTE inc;
418
419 TRACE_FUNCTION( "u_label_xid_valid" );
420
421 if (reset_received)
422 {
423 /* LLC informs GRLC to flush out LLC PDUs maintained in GRLC when XID reset
424 * is received by LLC */
425 PALLOC (grlc_flush_data_req, GRLC_FLUSH_DATA_REQ);
426 PSEND (hCommGRLC, grlc_flush_data_req);
427
428 /*
429 * First send reset indication, then handle it.
430 */
431 {
432 PALLOC (ll_reset_ind, LL_RESET_IND);
433 ll_reset_ind->sapi = llc_data->current_sapi;
434 TRACE_PRIM_TO("SND");
435 PSEND (hCommSNDCP, ll_reset_ind);
436 }
437 /*
438 * V(U) and V(UR) are set to 0. All services that are
439 * affected from ABM -> ADM are also reset.
440 */
441 sig_u_llme_reset_ind();
442 /*
443 * Check if the config primitive "DELAY" was received and wait
444 * for certain number of milliseconds
445 */
446 if (llc_data->millis > 0) {
447 TRACE_1_OUT_PARA("Sleeping for :%d milliseconds", llc_data->millis);
448 vsi_t_sleep(VSI_CALLER llc_data->millis);
449 }
450 /*
451 * After receiving a reset all running L3 requests should
452 * be ignored and no confirmation has to be send.
453 */
454 for (inc = 0; inc < U_NUM_INC; inc++)
455 {
456 SWITCH_SERVICE (llc, u, inc);
457
458 llc_data->u->release_requested = FALSE;
459 llc_data->u->ll_xid_resp_pending = FALSE;
460 }
461
462 /*
463 * Switch back to original SAPI
464 */
465 SWITCH_LLC (ll_unitdata_ind->sapi);
466 }
467
468 u_tag_xid_parameters (MS_RESPONSE, FALSE);
469
470 /*
471 * Check if we have to send an LL_XID_IND
472 */
473 if (llc_data->u->xid_tag & (0x00000001L << XID_N201_U) AND llc_data->u->requested_xid.n201_u.valid)
474 {
475 xid_ind = TRUE;
476 }
477 if (llc_data->u->xid_tag & (0x00000001L << XID_N201_I) AND llc_data->u->requested_xid.n201_i.valid)
478 {
479 xid_ind = TRUE;
480 }
481
482 /*
483 * If no Layer 3 XID parameters are included we don't have to wait
484 * for an LL_XID_RES
485 */
486 if (llc_data->decoded_l3_xid.valid NEQ TRUE)
487 {
488 /*
489 * Label S_XID_RES
490 */
491 u_send_xid (MS_RESPONSE);
492 }
493
494 if (xid_ind)
495 {
496 u_send_ll_xid_ind ();
497 }
498
499 if (reset_received)
500 {
501
502 /*
503 * V(U) and V(UR) are set to 0. All services that are
504 * affected from ABM -> ADM are also reset.
505 */
506 sig_u_llme_ready_ind();
507
508 /*
509 * Switch back to original SAPI
510 */
511 SWITCH_LLC (ll_unitdata_ind->sapi);
512 }
513
514
515
516 PFREE (ll_unitdata_ind);
517
518 return;
519 } /* u_label_xid_valid() */
520
521
522 /*
523 +------------------------------------------------------------------------------
524 | Function : u_label_frmr_cond
525 +------------------------------------------------------------------------------
526 | Description : Describes label FRMR_COND
527 |
528 | Parameters : ll_unitdata_ind - a valid pointer to the frame that caused the
529 | frame rejection condition
530 | cr_bit - C/R bit setting of frame
531 | frmr_reason - reason of frame rejection condition
532 |
533 +------------------------------------------------------------------------------
534 */
535 GLOBAL void u_label_frmr_cond (T_LL_UNITDATA_IND *ll_unitdata_ind,
536 T_BIT cr_bit,
537 UBYTE frmr_reason)
538 {
539 TRACE_FUNCTION ( "u_label_frmr_cond" );
540
541 u_send_llgmm_status_ind (LLGMM_ERRCS_FRMR_COND);
542
543 u_send_frmr (ll_unitdata_ind, U_FRAME, FRMR_CTRL_LENGTH_UNKNOWN,
544 llc_data->sapi->vs, llc_data->sapi->vr,
545 cr_bit, frmr_reason);
546
547 PFREE (ll_unitdata_ind);
548
549 return;
550 } /* u_label_frmr_cond() */
551
552
553 /*
554 +------------------------------------------------------------------------------
555 | Function : u_label_frmr_cond_reest
556 +------------------------------------------------------------------------------
557 | Description : Describes label FRMR_COND_REEST
558 |
559 | Parameters : ll_unitdata_ind - a valid pointer to the frame that caused the
560 | frame rejection condition
561 | cr_bit - C/R bit setting of frame
562 | frmr_reason - reason of frame rejection condition
563 |
564 +------------------------------------------------------------------------------
565 */
566 GLOBAL void u_label_frmr_cond_reest (T_LL_UNITDATA_IND *ll_unitdata_ind,
567 T_BIT cr_bit,
568 UBYTE frmr_reason)
569 {
570 TRACE_FUNCTION ( "u_label_frmr_cond_reest" );
571
572 u_send_llgmm_status_ind (LLGMM_ERRCS_FRMR_COND_REEST);
573
574 SET_STATE (U, U_LOCAL_ESTABLISHMENT);
575
576 sig_u_llme_abmrel_ind();
577
578 u_send_frmr (ll_unitdata_ind, U_FRAME, FRMR_CTRL_LENGTH_UNKNOWN,
579 llc_data->sapi->vs, llc_data->sapi->vr,
580 cr_bit, frmr_reason);
581
582 PFREE (ll_unitdata_ind);
583
584 llc_data->u->retransmission_counter = 0;
585
586 /*
587 * Send LL_ESTABLISH_IND after successful establishment.
588 */
589 llc_data->u->ind_cnf_establishment = IND_ESTABLISHMENT;
590
591 /*
592 * Re-establishment procedure: send GRLC_DATA_REQ (SABM), start T200.
593 */
594 u_send_sabm();
595
596 return;
597 } /* u_label_frmr_cond_reest() */
598
599
600 /*
601 +------------------------------------------------------------------------------
602 | Function : u_label_s_est_ind
603 +------------------------------------------------------------------------------
604 | Description : Describes label S_EST_IND
605 |
606 | Parameters : pf_bit - setting of P/F bit
607 |
608 +------------------------------------------------------------------------------
609 */
610 GLOBAL void u_label_s_est_ind (T_BIT pf_bit)
611 {
612 TRACE_FUNCTION ( "u_label_s_est_ind" );
613
614 SET_STATE (U, U_REMOTE_ESTABLISHMENT);
615
616 u_send_ll_establish_ind ();
617
618 sig_u_llme_abmrel_ind();
619
620 return;
621 } /* u_label_s_est_ind() */
622
623