FreeCalypso > hg > fc-tourmaline
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 |