FreeCalypso > hg > fc-magnetite
comparison src/g23m-gprs/llc/llc_us.c @ 183:219afcfc6250
src/g23m-gprs: initial import from TCS3.2/LoCosto
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 13 Oct 2016 04:24:13 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
182:f02d0a0e1849 | 183:219afcfc6250 |
---|---|
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 process internal signals as | |
19 | described in the SDL-documentation (U-statemachine) | |
20 +----------------------------------------------------------------------------- | |
21 */ | |
22 | |
23 #ifndef LLC_US_C | |
24 #define LLC_US_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 #include "llc_f.h" | |
41 | |
42 #include "llc_uf.h" /* to get local U functions */ | |
43 #include "llc_ul.h" /* to get local U labels */ | |
44 #include "llc_t200s.h" /* to get signal interface to T200 */ | |
45 #include "llc_txs.h" /* to get signal interface to TX */ | |
46 #include "llc_llmes.h" /* to get signal interface to LLME */ | |
47 | |
48 /*==== CONST ================================================================*/ | |
49 | |
50 /*==== LOCAL VARS ===========================================================*/ | |
51 | |
52 /*==== PRIVATE FUNCTIONS ====================================================*/ | |
53 | |
54 /*==== PUBLIC FUNCTIONS =====================================================*/ | |
55 | |
56 | |
57 | |
58 /* | |
59 +------------------------------------------------------------------------------ | |
60 | Function : sig_llme_u_assign_req | |
61 +------------------------------------------------------------------------------ | |
62 | Description : Handles the internal signal SIG_LLME_U_ASSIGN_REQ | |
63 | | |
64 | Parameters : | |
65 | | |
66 +------------------------------------------------------------------------------ | |
67 */ | |
68 GLOBAL void sig_llme_u_assign_req (void) | |
69 { | |
70 TRACE_ISIG( "sig_llme_u_assign_req" ); | |
71 | |
72 switch (GET_STATE(U)) | |
73 { | |
74 case U_TLLI_UNASSIGNED: | |
75 u_init_sapi(); | |
76 SET_STATE (U, U_ADM); | |
77 break; | |
78 default: | |
79 TRACE_ERROR( "SIG_LLME_U_ASSIGN_REQ unexpected" ); | |
80 break; | |
81 } | |
82 } /* sig_llme_u_assign_req() */ | |
83 | |
84 | |
85 | |
86 /* | |
87 +------------------------------------------------------------------------------ | |
88 | Function : sig_llme_u_unassign_req | |
89 +------------------------------------------------------------------------------ | |
90 | Description : Handles the internal signal SIG_LLME_U_UNASSIGN_REQ | |
91 | | |
92 | Parameters : | |
93 | | |
94 +------------------------------------------------------------------------------ | |
95 */ | |
96 GLOBAL void sig_llme_u_unassign_req (void) | |
97 { | |
98 TRACE_ISIG( "sig_llme_u_unassign_req" ); | |
99 | |
100 switch (GET_STATE(U)) | |
101 { | |
102 case U_TLLI_UNASSIGNED: | |
103 TRACE_ERROR( "SIG_LLME_U_UNASSIGN_REQ unexpected" ); | |
104 break; | |
105 | |
106 default: | |
107 sig_u_t200_stop_req(); | |
108 SET_STATE (U, U_TLLI_UNASSIGNED); | |
109 break; | |
110 } | |
111 } /* sig_llme_u_unassign_req() */ | |
112 | |
113 | |
114 | |
115 /* | |
116 +------------------------------------------------------------------------------ | |
117 | Function : sig_rx_u_data_ind | |
118 +------------------------------------------------------------------------------ | |
119 | Description : Handles the internal signal SIG_RX_U_DATA_IND | |
120 | | |
121 | Parameters : ll_unitdata_ind - a valid pointer to an LL-UNITDATA-IND | |
122 | primitive | |
123 | command - contains the command within the primitive | |
124 | cr_bit - setting of the C/R bit | |
125 | pf_bit - setting of the P/F bit | |
126 | | |
127 +------------------------------------------------------------------------------ | |
128 */ | |
129 GLOBAL void sig_rx_u_data_ind (T_LL_UNITDATA_IND *ll_unitdata_ind, | |
130 T_COMMAND command, | |
131 T_BIT cr_bit, | |
132 T_BIT pf_bit) | |
133 { | |
134 BOOL reset_received; | |
135 BOOL xid_ind; | |
136 BOOL rc_xid_valid; | |
137 BOOL l3p_outstanding; | |
138 | |
139 | |
140 TRACE_ISIG( "sig_rx_u_data_ind" ); | |
141 | |
142 /* | |
143 * Set TLLI for current transaction. | |
144 */ | |
145 llc_data->u->current_tlli = ll_unitdata_ind->tlli; | |
146 | |
147 switch (GET_STATE(U)) | |
148 { | |
149 case U_ADM: | |
150 if (cr_bit EQ SGSN_COMMAND) | |
151 { | |
152 /* | |
153 * Label ADM_COMMAND | |
154 */ | |
155 switch (command) | |
156 { | |
157 case U_SABM: /* COMMAND ADM */ | |
158 /* | |
159 * Label ADM_SABM | |
160 */ | |
161 if (pf_bit EQ 1) | |
162 { | |
163 if ( (llc_data->current_sapi EQ LL_SAPI_1) || | |
164 (llc_data->current_sapi EQ LL_SAPI_7) ) | |
165 { | |
166 /* | |
167 * ABM not possible on SAPI 1 and 7 | |
168 */ | |
169 PFREE (ll_unitdata_ind); | |
170 | |
171 u_send_dm (pf_bit); | |
172 } | |
173 else /* current_sapi is one of 3, 5, 9, or 11 */ | |
174 { | |
175 rc_xid_valid = u_check_xid (&(ll_unitdata_ind->sdu), | |
176 cr_bit, command); | |
177 | |
178 PFREE (ll_unitdata_ind); | |
179 | |
180 if (rc_xid_valid) | |
181 { | |
182 /* | |
183 * No check needed, reset_received cannot be TRUE | |
184 * (<R.LLC.XID_INVA.A.003>) and xid_ind is meaningless | |
185 * (LL_ESTABLISH_IND contains N201-U/I). | |
186 */ | |
187 u_eval_xid (cr_bit, &reset_received, &xid_ind); | |
188 | |
189 /* | |
190 * Check XID/SABM collision issue - XID command shall | |
191 * be treated as not transmitted. | |
192 */ | |
193 if (llc_data->u->xid_pending) | |
194 { | |
195 llc_data->u->xid_pending = FALSE; | |
196 | |
197 sig_u_t200_stop_req(); | |
198 } | |
199 | |
200 /* | |
201 * Label S_EST_IND | |
202 */ | |
203 u_label_s_est_ind (pf_bit); | |
204 } | |
205 } | |
206 } | |
207 else /* pf_bit is not set */ | |
208 { | |
209 PFREE (ll_unitdata_ind); | |
210 } | |
211 break; | |
212 | |
213 case U_XID: /* COMMAND ADM */ | |
214 /* | |
215 * Label XID | |
216 */ | |
217 u_label_xid (ll_unitdata_ind, command, cr_bit, pf_bit); | |
218 break; | |
219 | |
220 case U_DISC: /* COMMAND ADM */ | |
221 PFREE (ll_unitdata_ind); | |
222 if (pf_bit EQ 1) | |
223 { | |
224 u_send_dm (pf_bit); | |
225 } | |
226 break; | |
227 | |
228 default: | |
229 if (pf_bit EQ 1) | |
230 { | |
231 llc_data->u->frmr_reason = FRMR_UNDEFINED_CTRL; | |
232 /* | |
233 * Label FRMR_COND | |
234 */ | |
235 u_label_frmr_cond (ll_unitdata_ind, cr_bit, | |
236 llc_data->u->frmr_reason); | |
237 } | |
238 else | |
239 { | |
240 PFREE (ll_unitdata_ind); | |
241 } | |
242 break; | |
243 } | |
244 } | |
245 else /* SGSN_RESPONSE */ | |
246 { | |
247 /* | |
248 * Label ADM_RESPONSE | |
249 */ | |
250 switch (command) | |
251 { | |
252 case U_UA: /* RESPONSE ADM */ | |
253 PFREE (ll_unitdata_ind); | |
254 u_send_llgmm_status_ind (LLGMM_ERRCS_MULT_ASS_TLLI); | |
255 break; | |
256 | |
257 case U_DM: /* RESPONSE ADM */ | |
258 PFREE (ll_unitdata_ind); | |
259 break; | |
260 | |
261 case U_XID: /* RESPONSE ADM */ | |
262 /* | |
263 * Label XIDRES | |
264 */ | |
265 u_label_xidres (ll_unitdata_ind, command, cr_bit, pf_bit); | |
266 break; | |
267 | |
268 case U_FRMR: /* RESPONSE ADM */ | |
269 PFREE (ll_unitdata_ind); | |
270 u_send_llgmm_status_ind (LLGMM_ERRCS_FRMR_RECEIVED); | |
271 break; | |
272 | |
273 default: | |
274 llc_data->u->frmr_reason = FRMR_UNDEFINED_CTRL; | |
275 /* | |
276 * Label FRMR_COND | |
277 */ | |
278 u_label_frmr_cond (ll_unitdata_ind, cr_bit, | |
279 llc_data->u->frmr_reason); | |
280 break; | |
281 } | |
282 } | |
283 break; /* U_ADM */ | |
284 | |
285 case U_LOCAL_ESTABLISHMENT: | |
286 if (cr_bit EQ SGSN_COMMAND) | |
287 { | |
288 /* | |
289 * Label LEST_COMMAND | |
290 */ | |
291 switch (command) | |
292 { | |
293 case U_SABM: /* COMMAND LOCAL_ESTABLISHMENT */ | |
294 /* | |
295 * Label LEST_SABM | |
296 */ | |
297 | |
298 if (pf_bit EQ 1) | |
299 { | |
300 rc_xid_valid = u_check_xid (&ll_unitdata_ind->sdu, cr_bit, | |
301 command); | |
302 | |
303 PFREE (ll_unitdata_ind); | |
304 | |
305 if (rc_xid_valid) | |
306 { | |
307 if ((llc_data->decoded_l3_xid.valid EQ TRUE) AND | |
308 !(llc_data->u->xid_tag_sent & (0x00000001L << XID_LAYER_3))) | |
309 { | |
310 /* | |
311 * No check needed, reset_received cannot be TRUE | |
312 * (<R.LLC.XID_INVA.A.003>) and xid_ind is meaningless | |
313 * (LL_ESTABLISH_IND contains N201-U/I). | |
314 */ | |
315 u_eval_xid (cr_bit, &reset_received, &xid_ind); | |
316 | |
317 /* | |
318 * Label S_EST_IND | |
319 */ | |
320 u_label_s_est_ind (pf_bit); | |
321 } | |
322 } | |
323 } | |
324 else /* pf_bit is not set */ | |
325 { | |
326 PFREE (ll_unitdata_ind); | |
327 } | |
328 break; | |
329 | |
330 case U_DISC: /* COMMAND LOCAL_ESTABLISHMENT */ | |
331 PFREE (ll_unitdata_ind); | |
332 | |
333 if (pf_bit EQ 1) | |
334 { | |
335 PALLOC (ll_release_ind, LL_RELEASE_IND); | |
336 | |
337 ll_release_ind->sapi = llc_data->current_sapi; | |
338 #ifdef LL_2to1 | |
339 ll_release_ind->ps_cause.ctrl_value = CAUSE_is_from_llc; | |
340 ll_release_ind->ps_cause.value.llc_cause = LL_RELCS_NORMAL; | |
341 #else | |
342 ll_release_ind->cause = LL_RELCS_NORMAL; | |
343 #endif | |
344 | |
345 TRACE_1_OUT_PARA("s:%d", ll_release_ind->sapi); | |
346 PSEND (hCommSNDCP, ll_release_ind); | |
347 | |
348 u_send_dm (1); | |
349 | |
350 SET_STATE (U, U_ADM); | |
351 } | |
352 break; | |
353 | |
354 case U_XID: /* COMMAND LOCAL_ESTABLISHMENT */ | |
355 /* | |
356 * Label XID_SABM_SEND | |
357 */ | |
358 u_label_xid_sabm_send (ll_unitdata_ind, cr_bit, pf_bit); | |
359 break; | |
360 | |
361 default: | |
362 if (pf_bit EQ 1) | |
363 { | |
364 llc_data->u->frmr_reason = FRMR_UNDEFINED_CTRL; | |
365 | |
366 /* | |
367 * Label FRMR_COND | |
368 */ | |
369 u_label_frmr_cond (ll_unitdata_ind, cr_bit, | |
370 llc_data->u->frmr_reason); | |
371 } | |
372 else | |
373 { | |
374 PFREE (ll_unitdata_ind); | |
375 } | |
376 break; | |
377 } | |
378 } | |
379 else /* SGSN_RESPONSE */ | |
380 { | |
381 /* | |
382 * Label LEST_RESPONSE | |
383 */ | |
384 switch (command) | |
385 { | |
386 case U_UA: /* RESPONSE LOCAL_ESTABLISHMENT */ | |
387 /* | |
388 * Label LEST_UA | |
389 */ | |
390 | |
391 if (pf_bit EQ 1) | |
392 { | |
393 rc_xid_valid = u_check_xid (&ll_unitdata_ind->sdu, | |
394 cr_bit, command); | |
395 | |
396 if (rc_xid_valid) | |
397 { | |
398 l3p_outstanding = (llc_data->u->xid_tag_sent & (0x1L << XID_LAYER_3)) ? TRUE : FALSE; | |
399 | |
400 /* | |
401 * An UA response frame should only be handled if the XID L3 | |
402 * para are included or not same as requested. Else ignore it! | |
403 */ | |
404 if (llc_data->decoded_l3_xid.valid == l3p_outstanding) | |
405 { | |
406 /* | |
407 * <R.LLC.ABMEST_R.A.018> | |
408 */ | |
409 sig_u_t200_stop_req(); | |
410 | |
411 /* | |
412 * If an XID parameter is not included in the response and | |
413 * if it was included in the request, the requested value is | |
414 * implicit accepted. | |
415 */ | |
416 u_handle_optimization (); | |
417 | |
418 /* | |
419 * Reset_received cannot be TRUE, otherwise | |
420 * frame would not be valid | |
421 */ | |
422 u_eval_xid (cr_bit, &reset_received, &xid_ind); | |
423 | |
424 PFREE (ll_unitdata_ind); | |
425 | |
426 if (llc_data->u->release_requested == TRUE) | |
427 { | |
428 /* | |
429 * Do not send any establish confirmation to L3 and start | |
430 * release procedure | |
431 */ | |
432 llc_data->u->retransmission_counter = 0; | |
433 | |
434 SET_STATE (U, U_LOCAL_RELEASE); | |
435 | |
436 /* | |
437 * Send GRLC_DATA_REQ (DISC), start T200. | |
438 */ | |
439 u_send_disc(); | |
440 } | |
441 else | |
442 { | |
443 if (llc_data->u->ind_cnf_establishment EQ IND_ESTABLISHMENT) | |
444 { | |
445 u_send_ll_establish_ind (); | |
446 | |
447 SET_STATE (U, U_ESTABLISH_RES_PENDING); | |
448 | |
449 /* | |
450 * start ABM (re-)establish when establish response is received | |
451 */ | |
452 } | |
453 else /* CNF_ESTABLISHMENT */ | |
454 { | |
455 u_send_ll_establish_cnf (); | |
456 | |
457 SET_STATE (U, U_ABM); | |
458 | |
459 /* | |
460 * inform LLME about (re-)establischment | |
461 */ | |
462 sig_u_llme_abmest_ind(); | |
463 } | |
464 } | |
465 } | |
466 else | |
467 { | |
468 PFREE (ll_unitdata_ind); | |
469 } | |
470 } | |
471 else | |
472 { | |
473 PFREE (ll_unitdata_ind); | |
474 | |
475 /* | |
476 * request T200 to let the timer manually expire, | |
477 * thus retransmitting the frame immediately | |
478 */ | |
479 sig_u_t200_expire_req (); | |
480 | |
481 /* SET_STATE (U, SAME_STATE); */ | |
482 } | |
483 } | |
484 else /* pf_bit == 0 */ | |
485 { | |
486 PFREE (ll_unitdata_ind); | |
487 | |
488 u_send_llgmm_status_ind (LLGMM_ERRCS_MULT_ASS_TLLI); | |
489 | |
490 /* SET_STATE (U, SAME_STATE); */ | |
491 } | |
492 break; | |
493 | |
494 case U_DM: /* RESPONSE LOCAL_ESTABLISHMENT */ | |
495 /* | |
496 * Label LEST_DM | |
497 */ | |
498 PFREE (ll_unitdata_ind); | |
499 | |
500 if (pf_bit EQ 1) | |
501 { | |
502 sig_u_t200_stop_req(); | |
503 | |
504 if (llc_data->u->release_requested == TRUE) | |
505 { | |
506 u_send_ll_release_cnf (); | |
507 } | |
508 else | |
509 { | |
510 u_send_ll_release_ind (LL_RELCS_DM_RECEIVED); | |
511 } | |
512 | |
513 SET_STATE (U, U_ADM); | |
514 } | |
515 break; | |
516 | |
517 case U_XID: /* RESPONSE LOCAL_ESTABLISHMENT */ | |
518 /* | |
519 * Label XIDRES | |
520 */ | |
521 u_label_xidres (ll_unitdata_ind, command, cr_bit, pf_bit); | |
522 break; | |
523 | |
524 case U_FRMR: /* RESPONSE LOCAL_ESTABLISHMENT */ | |
525 PFREE (ll_unitdata_ind); | |
526 u_send_llgmm_status_ind (LLGMM_ERRCS_FRMR_RECEIVED); | |
527 break; | |
528 | |
529 default: | |
530 llc_data->u->frmr_reason = FRMR_UNDEFINED_CTRL; | |
531 | |
532 /* | |
533 * Label FRMR_COND | |
534 */ | |
535 u_label_frmr_cond (ll_unitdata_ind, cr_bit, | |
536 llc_data->u->frmr_reason); | |
537 break; | |
538 } | |
539 } | |
540 break; /* U_LOCAL_ESTABLISHMENT */ | |
541 | |
542 case U_ABM: | |
543 if (cr_bit EQ SGSN_COMMAND) | |
544 { | |
545 /* | |
546 * Label ABM_COMMAND | |
547 */ | |
548 switch (command) | |
549 { | |
550 case U_SABM: /* COMMAND ABM */ | |
551 /* | |
552 * Label ABM_REEST_PEER | |
553 */ | |
554 if (pf_bit EQ 1) | |
555 { | |
556 u_send_llgmm_status_ind (LLGMM_ERRCS_PEER_REEST); | |
557 | |
558 rc_xid_valid = u_check_xid (&ll_unitdata_ind->sdu, | |
559 cr_bit, command); | |
560 | |
561 PFREE (ll_unitdata_ind); | |
562 | |
563 if (rc_xid_valid) | |
564 { | |
565 /* | |
566 * No check needed, reset_received cannot be TRUE | |
567 * (<R.LLC.XID_INVA.A.003>) and xid_ind is meaningless | |
568 * (LL_ESTABLISH_IND contains N201-U/I). | |
569 */ | |
570 u_eval_xid (cr_bit, &reset_received, &xid_ind); | |
571 | |
572 /* | |
573 * Label S_EST_IND | |
574 */ | |
575 u_label_s_est_ind (pf_bit); | |
576 } | |
577 } | |
578 else /* pf_bit == 0 */ | |
579 { | |
580 PFREE (ll_unitdata_ind); | |
581 } | |
582 break; | |
583 | |
584 case U_DISC: /* COMMAND ABM */ | |
585 /* | |
586 * Label ABM_DISC | |
587 */ | |
588 PFREE (ll_unitdata_ind); | |
589 | |
590 if (pf_bit EQ 1) | |
591 { | |
592 PALLOC (ll_release_ind, LL_RELEASE_IND); | |
593 | |
594 ll_release_ind->sapi = llc_data->current_sapi; | |
595 #ifdef LL_2to1 | |
596 ll_release_ind->ps_cause.ctrl_value = CAUSE_is_from_llc; | |
597 ll_release_ind->ps_cause.value.llc_cause = LL_RELCS_NORMAL; | |
598 #else | |
599 ll_release_ind->cause = LL_RELCS_NORMAL; | |
600 #endif | |
601 TRACE_1_OUT_PARA("s:%d", ll_release_ind->sapi); | |
602 PSEND (hCommSNDCP, ll_release_ind); | |
603 | |
604 SET_STATE (U, U_ADM); | |
605 | |
606 sig_u_llme_abmrel_ind(); | |
607 | |
608 /* | |
609 * Send UA response without XID information field (= FALSE). | |
610 */ | |
611 u_send_ua (pf_bit, FALSE); | |
612 } | |
613 break; | |
614 | |
615 case U_XID: /* COMMAND ABM */ | |
616 /* | |
617 * Label XID | |
618 */ | |
619 u_label_xid (ll_unitdata_ind, command, cr_bit, pf_bit); | |
620 break; | |
621 | |
622 default: | |
623 if (pf_bit EQ 1) | |
624 { | |
625 llc_data->u->frmr_reason = FRMR_UNDEFINED_CTRL_ABM; | |
626 | |
627 /* | |
628 * Label FRMR_COND_REEST | |
629 */ | |
630 u_label_frmr_cond_reest (ll_unitdata_ind, cr_bit, | |
631 llc_data->u->frmr_reason); | |
632 } | |
633 else | |
634 { | |
635 PFREE (ll_unitdata_ind); | |
636 } | |
637 break; | |
638 } | |
639 } | |
640 else /* SGSN_RESPONSE */ | |
641 { | |
642 /* | |
643 * Label ABM_RESPONSE | |
644 */ | |
645 switch (command) | |
646 { | |
647 case U_UA: /* RESPONSE ABM */ | |
648 /* | |
649 * Label ABM_UA | |
650 */ | |
651 PFREE (ll_unitdata_ind); | |
652 u_send_llgmm_status_ind (LLGMM_ERRCS_MULT_ASS_TLLI); | |
653 break; | |
654 | |
655 case U_DM: /* RESPONSE ABM */ | |
656 /* | |
657 * Label ABM_DM | |
658 */ | |
659 PFREE (ll_unitdata_ind); | |
660 | |
661 if (pf_bit EQ 1) | |
662 { | |
663 u_send_llgmm_status_ind (LLGMM_ERRCS_DM1_RECEIVED); | |
664 } | |
665 else /* pf_bit == 0 */ | |
666 { | |
667 u_send_llgmm_status_ind (LLGMM_ERRCS_DM0_RECEIVED_REEST); | |
668 | |
669 llc_data->u->retransmission_counter = 0; | |
670 | |
671 /* | |
672 * Send LL_ESTABLISH_IND after successful establishment. | |
673 */ | |
674 llc_data->u->ind_cnf_establishment = IND_ESTABLISHMENT; | |
675 | |
676 SET_STATE (U, U_LOCAL_ESTABLISHMENT); | |
677 | |
678 sig_u_llme_abmrel_ind(); | |
679 | |
680 /* | |
681 * Re-establishment procedure: send GRLC_DATA_REQ (SABM), | |
682 * start T200. | |
683 */ | |
684 u_send_sabm(); | |
685 } | |
686 break; | |
687 | |
688 case U_XID: /* RESPONSE ABM */ | |
689 /* | |
690 * Label XIDRES | |
691 */ | |
692 u_label_xidres (ll_unitdata_ind, command, cr_bit, pf_bit); | |
693 break; | |
694 | |
695 case U_FRMR: /* RESPONSE ABM */ | |
696 PFREE (ll_unitdata_ind); | |
697 u_send_llgmm_status_ind (LLGMM_ERRCS_FRMR_RECEIVED); | |
698 break; | |
699 | |
700 default: | |
701 llc_data->u->frmr_reason = FRMR_UNDEFINED_CTRL_ABM; | |
702 | |
703 /* | |
704 * Label FRMR_COND_REEST | |
705 */ | |
706 u_label_frmr_cond_reest (ll_unitdata_ind, cr_bit, | |
707 llc_data->u->frmr_reason); | |
708 break; | |
709 } | |
710 } | |
711 break; /* U_ABM */ | |
712 | |
713 case U_LOCAL_RELEASE: | |
714 if (cr_bit EQ SGSN_COMMAND) | |
715 { | |
716 /* | |
717 * Label LREL_COMMAND | |
718 */ | |
719 switch (command) | |
720 { | |
721 case U_SABM: /* COMMAND LOCAL_RELEASE */ | |
722 PFREE (ll_unitdata_ind); | |
723 | |
724 if (pf_bit EQ 1) | |
725 { | |
726 /* | |
727 * Send DM response with F bit set to 1. | |
728 */ | |
729 u_send_dm (1); | |
730 } | |
731 break; | |
732 | |
733 case U_DISC: /* COMMAND LOCAL_RELEASE */ | |
734 PFREE (ll_unitdata_ind); | |
735 | |
736 if (pf_bit EQ 1) | |
737 { | |
738 /* | |
739 * Send UA response with F bit set to 1, but without information | |
740 * field (= FALSE). | |
741 */ | |
742 u_send_ua (1, FALSE); | |
743 } | |
744 break; | |
745 | |
746 case U_XID: /* COMMAND LOCAL_RELEASE */ | |
747 /* | |
748 * Label XID | |
749 */ | |
750 u_label_xid (ll_unitdata_ind, command, cr_bit, pf_bit); | |
751 break; | |
752 | |
753 default: | |
754 if (pf_bit EQ 1) | |
755 { | |
756 llc_data->u->frmr_reason = FRMR_UNDEFINED_CTRL; | |
757 | |
758 /* | |
759 * Label FRMR_COND | |
760 */ | |
761 u_label_frmr_cond (ll_unitdata_ind, cr_bit, | |
762 llc_data->u->frmr_reason); | |
763 } | |
764 else | |
765 { | |
766 PFREE (ll_unitdata_ind); | |
767 } | |
768 break; | |
769 } | |
770 } | |
771 else /* SGSN_RESPONSE */ | |
772 { | |
773 /* | |
774 * Label LREL_RESPONSE | |
775 */ | |
776 switch (command) | |
777 { | |
778 case U_UA: /* RESPONSE LOCAL_RELEASE */ | |
779 /* | |
780 * no break! | |
781 */ | |
782 case U_DM: /* RESPONSE LOCAL_RELEASE */ | |
783 /* | |
784 * Label LREL_UA_DM | |
785 */ | |
786 PFREE (ll_unitdata_ind); | |
787 | |
788 if (pf_bit EQ 1) | |
789 { | |
790 SET_STATE (U, U_ADM); | |
791 | |
792 sig_u_t200_stop_req(); | |
793 | |
794 u_send_ll_release_cnf(); | |
795 } | |
796 else /* pf_bit == 0 */ | |
797 { | |
798 if (command EQ U_UA) | |
799 { | |
800 u_send_llgmm_status_ind (LLGMM_ERRCS_MULT_ASS_TLLI); | |
801 } | |
802 } | |
803 break; | |
804 | |
805 case U_XID: /* RESPONSE LOCAL_RELEASE */ | |
806 /* | |
807 * Label XIDRES | |
808 */ | |
809 u_label_xidres (ll_unitdata_ind, command, cr_bit, pf_bit); | |
810 break; | |
811 | |
812 case U_FRMR: /* RESPONSE LOCAL_RELEASE */ | |
813 PFREE (ll_unitdata_ind); | |
814 u_send_llgmm_status_ind (LLGMM_ERRCS_FRMR_RECEIVED); | |
815 break; | |
816 | |
817 default: | |
818 llc_data->u->frmr_reason = FRMR_UNDEFINED_CTRL; | |
819 | |
820 /* | |
821 * Label FRMR_COND | |
822 */ | |
823 u_label_frmr_cond (ll_unitdata_ind, cr_bit, | |
824 llc_data->u->frmr_reason); | |
825 break; | |
826 } | |
827 } | |
828 break; /* U_LOCAL_RELEASE */ | |
829 | |
830 default: | |
831 PFREE (ll_unitdata_ind); | |
832 TRACE_ERROR( "SIG_RX_U_DATA_IND unexpected" ); | |
833 break; | |
834 } | |
835 } /* sig_rx_u_data_ind() */ | |
836 | |
837 | |
838 /* | |
839 +------------------------------------------------------------------------------ | |
840 | Function : sig_rx_u_frmr_ind | |
841 +------------------------------------------------------------------------------ | |
842 | Description : Handles the internal signal SIG_RX_U_FRMR_IND | |
843 | | |
844 | Parameters : ll_unitdata_ind - valid pointer to the frame that caused the | |
845 | frame rejection condition | |
846 | pdu_type - type of frame | |
847 | frmr_ctrl_length - length of frame control field, if known | |
848 | cr_bit - C/R bit setting of frame | |
849 | frmr_reason - reason of frame rejection condition | |
850 | | |
851 +------------------------------------------------------------------------------ | |
852 */ | |
853 GLOBAL void sig_rx_u_frmr_ind (T_LL_UNITDATA_IND *ll_unitdata_ind, | |
854 T_PDU_TYPE pdu_type, | |
855 USHORT frmr_ctrl_length, | |
856 T_BIT cr_bit, | |
857 UBYTE frmr_reason) | |
858 { | |
859 TRACE_ISIG( "sig_rx_u_frmr_ind" ); | |
860 | |
861 /* | |
862 * Set TLLI for current transaction. | |
863 */ | |
864 llc_data->u->current_tlli = ll_unitdata_ind->tlli; | |
865 | |
866 switch (GET_STATE (U)) | |
867 { | |
868 case U_ADM: | |
869 case U_LOCAL_ESTABLISHMENT: | |
870 case U_ESTABLISH_RES_PENDING: | |
871 case U_REMOTE_ESTABLISHMENT: | |
872 /* | |
873 * No break! | |
874 */ | |
875 case U_LOCAL_RELEASE: | |
876 u_send_llgmm_status_ind (LLGMM_ERRCS_FRMR_COND); | |
877 | |
878 u_send_frmr (ll_unitdata_ind, pdu_type, frmr_ctrl_length, | |
879 llc_data->sapi->vs, llc_data->sapi->vr, | |
880 cr_bit, frmr_reason); | |
881 | |
882 PFREE (ll_unitdata_ind); | |
883 break; | |
884 case U_ABM: | |
885 u_send_llgmm_status_ind (LLGMM_ERRCS_FRMR_COND_REEST); | |
886 | |
887 SET_STATE (U, U_LOCAL_ESTABLISHMENT); | |
888 | |
889 /* | |
890 * Set bit W4 in frmr_reason to indicate ABM mode. | |
891 */ | |
892 frmr_reason |= FRMR_W4; | |
893 | |
894 u_send_frmr (ll_unitdata_ind, pdu_type, frmr_ctrl_length, | |
895 llc_data->sapi->vs, llc_data->sapi->vr, | |
896 cr_bit, frmr_reason); | |
897 | |
898 sig_u_llme_abmrel_ind(); | |
899 | |
900 PFREE (ll_unitdata_ind); | |
901 | |
902 llc_data->u->retransmission_counter = 0; | |
903 | |
904 /* | |
905 * Send LL_ESTABLISH_IND after successful establishment. | |
906 */ | |
907 llc_data->u->ind_cnf_establishment = IND_ESTABLISHMENT; | |
908 | |
909 /* | |
910 * Re-establishment procedure: send GRLC_DATA_REQ (SABM), start T200. | |
911 */ | |
912 u_send_sabm(); | |
913 break; | |
914 default: | |
915 PFREE (ll_unitdata_ind); | |
916 TRACE_ERROR( "SIG_RX_U_FRMR_IND unexpected" ); | |
917 break; | |
918 } | |
919 | |
920 } /* sig_rx_u_frmr_ind() */ | |
921 | |
922 | |
923 /* | |
924 +------------------------------------------------------------------------------ | |
925 | Function : sig_t200_u_expired_ind | |
926 +------------------------------------------------------------------------------ | |
927 | Description : Handles the internal signal SIG_T200_U_EXPIRED_IND | |
928 | | |
929 | Parameters : grlc_data_req - a valid pointer to the frame (primitive) that | |
930 | is associated with the timer | |
931 | | |
932 +------------------------------------------------------------------------------ | |
933 */ | |
934 GLOBAL void sig_t200_u_expired_ind | |
935 ( | |
936 #ifndef LL_DESC | |
937 T_LL_UNITDATA_REQ *ll_unitdesc_req, | |
938 #else | |
939 T_LL_UNITDESC_REQ *ll_unitdesc_req, | |
940 #endif | |
941 UBYTE cause, | |
942 T_EXPIRY_MODE_TYPE mode | |
943 ) | |
944 { | |
945 UBYTE u_state; | |
946 | |
947 TRACE_ISIG( "sig_t200_u_expired_ind" ); | |
948 | |
949 /* | |
950 * Set TLLI for current transaction. | |
951 */ | |
952 llc_data->u->current_tlli = llc_data->tlli_new; | |
953 | |
954 u_state = GET_STATE(U); | |
955 switch (u_state) | |
956 { | |
957 case U_LOCAL_ESTABLISHMENT: | |
958 /* | |
959 * First check if an L3 release requested is pendling | |
960 */ | |
961 if (llc_data->u->release_requested == TRUE) | |
962 { | |
963 /* | |
964 * Do not restart timer. Send the release confirm. | |
965 */ | |
966 #ifdef LL_DESC | |
967 llc_cl_desc3_free((T_desc3*)ll_unitdesc_req->desc_list3.first); | |
968 #endif /* LL_DESC */ | |
969 PFREE (ll_unitdesc_req); | |
970 | |
971 u_send_ll_release_cnf(); | |
972 | |
973 SET_STATE (U, U_ADM); | |
974 } | |
975 else | |
976 { | |
977 /* | |
978 * Increment retransmission_counter. | |
979 */ | |
980 llc_data->u->retransmission_counter++; | |
981 | |
982 if (llc_data->u->retransmission_counter <= *(llc_data->n200)) | |
983 { | |
984 /* | |
985 * T200 has to be started before the primitive is sent to TX, because | |
986 * the primitive is copied by t200_start() and it may not be valid | |
987 * anymore after sending to TX. | |
988 */ | |
989 sig_u_t200_start_req (ll_unitdesc_req, cause); | |
990 | |
991 sig_u_tx_data_req (ll_unitdesc_req, cause); | |
992 } | |
993 else /* retransmission_counter exceeds N200 */ | |
994 { | |
995 #ifdef LL_DESC | |
996 llc_cl_desc3_free((T_desc3*)ll_unitdesc_req->desc_list3.first); | |
997 #endif /* LL_DESC */ | |
998 PFREE (ll_unitdesc_req); | |
999 | |
1000 /* | |
1001 * Label LEST_N200 | |
1002 */ | |
1003 | |
1004 u_send_llgmm_status_ind (LLGMM_ERRCS_SABM_NO_PEER_RES); | |
1005 | |
1006 if (mode == EXPIRY_TIMED) | |
1007 { | |
1008 u_send_ll_release_ind (LL_RELCS_NO_PEER_RES); | |
1009 } | |
1010 else /* EXPIRY_REQUESTED */ | |
1011 { | |
1012 /* | |
1013 * <R.LLC.ABMEST_R.A.015> | |
1014 * vs. <R.LLC.ABMEST_R.A.030> | |
1015 */ | |
1016 u_send_ll_release_ind (LL_RELCS_INVALID_XID); | |
1017 } | |
1018 | |
1019 SET_STATE (U, U_ADM); | |
1020 } | |
1021 } | |
1022 break; /* U_LOCAL_ESTABLISHMENT */ | |
1023 | |
1024 case U_LOCAL_RELEASE: | |
1025 /* | |
1026 * First check if an L3 release requested is pendling | |
1027 */ | |
1028 if (llc_data->u->release_requested == TRUE) | |
1029 { | |
1030 /* | |
1031 * Do not restart timer. Send the release confirm. | |
1032 */ | |
1033 #ifdef LL_DESC | |
1034 llc_cl_desc3_free((T_desc3*)ll_unitdesc_req->desc_list3.first); | |
1035 #endif /* LL_DESC */ | |
1036 PFREE (ll_unitdesc_req); | |
1037 | |
1038 u_send_ll_release_cnf(); | |
1039 | |
1040 SET_STATE (U, U_ADM); | |
1041 } | |
1042 else | |
1043 { | |
1044 /* | |
1045 * Increment retransmission_counter. | |
1046 */ | |
1047 llc_data->u->retransmission_counter++; | |
1048 | |
1049 if (llc_data->u->retransmission_counter <= *(llc_data->n200)) | |
1050 { | |
1051 /* | |
1052 * T200 has to be started before the primitive is sent to TX, because | |
1053 * the primitive is copied by t200_start() and it may not be valid | |
1054 * anymore after sending to TX. | |
1055 */ | |
1056 sig_u_t200_start_req (ll_unitdesc_req, cause); | |
1057 sig_u_tx_data_req (ll_unitdesc_req, cause); | |
1058 } | |
1059 else /* retransmission_counter exceeds N200 */ | |
1060 { | |
1061 #ifdef LL_DESC | |
1062 llc_cl_desc3_free((T_desc3*)ll_unitdesc_req->desc_list3.first); | |
1063 #endif /* LL_DESC */ | |
1064 PFREE (ll_unitdesc_req); | |
1065 | |
1066 SET_STATE (U, U_ADM); | |
1067 | |
1068 u_send_llgmm_status_ind (LLGMM_ERRCS_DISC_NO_PEER_RES); | |
1069 u_send_ll_release_cnf (); | |
1070 } | |
1071 } | |
1072 break; | |
1073 | |
1074 case U_ADM: | |
1075 case U_ABM: | |
1076 llc_data->u->retransmission_counter++; | |
1077 if (llc_data->u->retransmission_counter <= *(llc_data->n200)) | |
1078 { | |
1079 /* If T200 expires and needs to send SABM the state should | |
1080 * be set properly | |
1081 */ | |
1082 if (u_state == U_ADM AND | |
1083 llc_data->u->xid_pending NEQ TRUE ) | |
1084 { | |
1085 SET_STATE (U,U_LOCAL_ESTABLISHMENT); | |
1086 } | |
1087 /* | |
1088 * T200 has to be started before the primitive is sent to TX, because | |
1089 * the primitive is copied by t200_start() and it may not be valid | |
1090 * anymore after sending to TX. | |
1091 */ | |
1092 sig_u_t200_start_req (ll_unitdesc_req, cause); | |
1093 sig_u_tx_data_req (ll_unitdesc_req, cause); | |
1094 | |
1095 /* SET_STATE (U, SAME_STATE); */ | |
1096 } | |
1097 else | |
1098 { | |
1099 #ifdef LL_DESC | |
1100 llc_cl_desc3_free((T_desc3*)ll_unitdesc_req->desc_list3.first); | |
1101 #endif /* LL_DESC */ | |
1102 PFREE (ll_unitdesc_req); | |
1103 | |
1104 /* | |
1105 * Label XIDSENT_N200 | |
1106 */ | |
1107 | |
1108 u_send_llgmm_status_ind (LLGMM_ERRCS_XID_NO_PEER_RES); | |
1109 | |
1110 if (llc_data->u->xid_pending) | |
1111 { | |
1112 llc_data->u->xid_pending = FALSE; | |
1113 } | |
1114 | |
1115 if (u_state == U_ADM) | |
1116 { | |
1117 if (llc_data->u->xid_tag_sent & (0x00000001L << XID_LAYER_3)) | |
1118 { | |
1119 if (mode == EXPIRY_TIMED) | |
1120 { | |
1121 u_send_ll_status_ind (LL_ERRCS_NO_PEER_RES); | |
1122 } | |
1123 else /* EXPIRY_REQUESTED */ | |
1124 { | |
1125 u_send_ll_status_ind (LL_ERRCS_INVALID_XID); | |
1126 } | |
1127 } | |
1128 | |
1129 /* SET_STATE (U, SAME_STATE); */ | |
1130 } | |
1131 else /* U_ABM */ | |
1132 { | |
1133 if (mode == EXPIRY_TIMED) | |
1134 { | |
1135 u_send_ll_release_ind (LL_RELCS_NO_PEER_RES); | |
1136 } | |
1137 else /* EXPIRY_REQUESTED */ | |
1138 { | |
1139 /* | |
1140 * <R.LLC.XIDNEG_O.A.016> | |
1141 * vs. <R.LLC.XIDNEG_O.A.022> | |
1142 */ | |
1143 u_send_ll_release_ind (LL_RELCS_INVALID_XID); | |
1144 } | |
1145 | |
1146 SET_STATE (U, U_ADM); | |
1147 | |
1148 sig_u_llme_abmrel_ind(); | |
1149 } | |
1150 } | |
1151 break; | |
1152 | |
1153 default: | |
1154 #ifdef LL_DESC | |
1155 llc_cl_desc3_free((T_desc3*)ll_unitdesc_req->desc_list3.first); | |
1156 #endif /* LL_DESC */ | |
1157 PFREE (ll_unitdesc_req); | |
1158 TRACE_ERROR( "SIG_T200_U_EXPIRED_IND unexpected" ); | |
1159 break; | |
1160 } | |
1161 } /* sig_t200_u_expired_ind() */ | |
1162 | |
1163 | |
1164 /* | |
1165 +------------------------------------------------------------------------------ | |
1166 | Function : sig_llme_u_reest_req | |
1167 +------------------------------------------------------------------------------ | |
1168 | Description : Handles the internal signal SIG_LLME_U_REEST_REQ | |
1169 | | |
1170 | Parameters : | |
1171 | | |
1172 +------------------------------------------------------------------------------ | |
1173 */ | |
1174 GLOBAL void sig_llme_u_reest_req ( void ) | |
1175 { | |
1176 TRACE_FUNCTION( "sig_llme_u_reest_req" ); | |
1177 | |
1178 switch (GET_STATE(U)) | |
1179 { | |
1180 case U_ABM: | |
1181 llc_data->u->retransmission_counter = 0; | |
1182 | |
1183 /* | |
1184 * Send LL_ESTABLISH_IND after successful re-establishment. | |
1185 */ | |
1186 llc_data->u->ind_cnf_establishment = IND_ESTABLISHMENT; | |
1187 | |
1188 SET_STATE (U, U_LOCAL_ESTABLISHMENT); | |
1189 | |
1190 /* | |
1191 * Send GRLC_DATA_REQ (SABM), start T200. | |
1192 */ | |
1193 u_send_sabm(); | |
1194 break; | |
1195 | |
1196 default: | |
1197 TRACE_ERROR( "SIG_LLME_U_REEST_REQ unexpected" ); | |
1198 break; | |
1199 } | |
1200 | |
1201 } /* sig_llme_u_reest_req() */ | |
1202 | |
1203 /* | |
1204 +------------------------------------------------------------------------------ | |
1205 | Function : sig_irx_u_no_frame_expected_ind | |
1206 +------------------------------------------------------------------------------ | |
1207 | Description : Handles the internal signal SIG_IRX_U_NO_FRAME_EXPECTED_IND | |
1208 | | |
1209 | Parameters : | |
1210 | | |
1211 +------------------------------------------------------------------------------ | |
1212 */ | |
1213 GLOBAL void sig_irx_u_no_frame_expected_ind ( void ) | |
1214 { | |
1215 TRACE_FUNCTION( "sig_irx_u_no_frame_expected_ind" ); | |
1216 | |
1217 switch (GET_STATE(U)) | |
1218 { | |
1219 case U_ADM: | |
1220 /* | |
1221 * An LLE shall transmit a DM resonse to any valid command received | |
1222 * that it cannot action: GSM 04.64 Ver 6.7.0 Chapter 6.4.1.4 | |
1223 * Upon receiption of an I+S frame in ADM state, the MS shall send | |
1224 * a DM response with F bit set 0. | |
1225 */ | |
1226 u_send_dm (0); | |
1227 break; | |
1228 | |
1229 case U_LOCAL_ESTABLISHMENT: | |
1230 case U_ESTABLISH_RES_PENDING: | |
1231 case U_REMOTE_ESTABLISHMENT: | |
1232 /* | |
1233 * Ignore S- and I/S-frames received while ABM establishment. Do | |
1234 * not send any response: GSM 04.64 Ver 6.7.0 Chapter 8.5.1.1 | |
1235 */ | |
1236 break; | |
1237 | |
1238 case U_LOCAL_RELEASE: | |
1239 /* | |
1240 * Ignore S- and I/S-frames received while ABM termination. Do | |
1241 * not send any response: GSM 04.64 Ver 6.7.0 Chapter 8.5.2.1 | |
1242 */ | |
1243 break; | |
1244 | |
1245 case U_ABM: | |
1246 default: | |
1247 TRACE_ERROR( "SIG_IRX_U_NO_FRAME_EXPECTED_IND unexpected" ); | |
1248 break; | |
1249 } | |
1250 | |
1251 } /* sig_irx_u_no_frame_expected_ind() */ | |
1252 |