comparison gsm-fw/g23m-gsm/cc/cc_rel.c @ 673:2f7df7a314f8

gsm-fw/g23m-gsm subtree: initial import from LoCosto source
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 28 Sep 2014 23:20:04 +0000
parents
children 7204091241d0
comparison
equal deleted inserted replaced
672:0dc6f9e8e980 673:2f7df7a314f8
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GSM-PS (6147)
4 | Modul : CC_REL
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 defines the functions for call release
18 | of the component CC of the mobile station.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef CC_REL_C
23 #define CC_REL_C
24
25 #define ENTITY_CC
26 /*==== INCLUDES ===================================================*/
27
28 #include <string.h>
29 #include "typedefs.h"
30 #include "pcm.h"
31 #include "vsi.h"
32 #include "custom.h"
33 #include "gsm.h"
34 #include "message.h"
35 #include "ccdapi.h"
36 #include "prim.h"
37 #include "cnf_cc.h"
38 #include "mon_cc.h"
39 #include "pei.h"
40 #include "tok.h"
41 #include "cc.h"
42 #include "cc_em.h"
43
44 /*==== EXPORT =====================================================*/
45
46 /*==== PROTOTYPES =================================================*/
47 /* Implements Measure# 8 */
48 LOCAL void cc_mncc_release_ind (T_PRIM * prim);
49 /* Implements Measure# 9 */
50 LOCAL void cc_mncc_release_cnf (T_PRIM * prim);
51 /* Implements Measure# 41 */
52 LOCAL void cc_mncc_sync_ind ( UBYTE ti,
53 UBYTE new_state);
54 /*==== PRIVAT =====================================================*/
55
56 /*==== VARIABLES ==================================================*/
57
58 /*==== FUNCTIONS ==================================================*/
59
60 /*
61 +--------------------------------------------------------------------+
62 | PROJECT : GSM-PS (6147) MODULE : CC_REL |
63 | STATE : code ROUTINE : cc_check_setup_reattempt |
64 +--------------------------------------------------------------------+
65
66 PURPOSE : This function checks whether a the mobile originated setup
67 may be reattempted. This will be done for some certain
68 reasons which may indicate network failure.
69 This function is considered as a hack only
70 for networks which tend to deliver a poor quality
71 of service only (e.g. typically in China).
72 This behaviour or the algorithm is not specified / implied
73 by GSM but driven by customer requests and the desire
74 to have a good, working product.
75 */
76
77 LOCAL void cc_check_setup_reattempt ( const T_M_CC_cc_cause *cc_cause)
78 {
79 GET_INSTANCE_DATA;
80 EXTERN BOOL poor_quality_network;
81
82 TRACE_FUNCTION ("cc_check_setup_reattempt()");
83
84 #ifdef WIN32
85 /*
86 * Set poor_quality_network for test, pei_config() is the appropriate place,
87 * but this seems not to be working for some strange reasons
88 */
89 poor_quality_network = TRUE;
90 #endif
91
92 /* reattempt already "running", see cc_setup_reattempt for further reasoning */
93 if (cc_data->setup_reattempt_ti NEQ NOT_PRESENT_8BIT)
94 return;
95
96 switch (cc_data->state[cc_data->index_ti])
97 {
98 case M_CC_CS_1: /* call initiated */
99 case M_CC_CS_3: /* mobile originating call proceeding */
100 cc_data->setup_attempts++;
101 if (poor_quality_network AND
102 (cc_data->setup_attempts < MAX_SETUP_ATTEMPTS) AND
103 (cc_cause->v_cause))
104 {
105 /*
106 * Mobile originated call got disconnect,
107 * max. number of setup attempts not reached.
108 * New dial attempt for certain disconnect reasons
109 */
110 switch (cc_cause->cause)
111 {
112 case M_CC_CAUSE_NO_CHAN_AVAIL: /* #34 */
113 case M_CC_CAUSE_NETWORK_ORDER: /* #38 */
114 case M_CC_CAUSE_TEMP_FAIL: /* #41 */
115 case M_CC_CAUSE_SWITCH_CONGEST: /* #42 */
116 case M_CC_CAUSE_INFO_DISCARD: /* #43 */
117 case M_CC_CAUSE_REQ_CHAN_UNAVAIL: /* #44 */
118 case M_CC_CAUSE_RESOURCE_UNAVAIL: /* #47 */
119 case M_CC_CAUSE_QOS_UNAVAIL: /* #49 */
120 case M_CC_CAUSE_BEARER_CAP_UNAVAIL: /* #58 */
121 case M_CC_CAUSE_TIMER: /* #102 */
122 case M_CC_CAUSE_INTERWORKING: /* #127 */
123 /*
124 * Maybe some more causes to added here
125 * which indicate network failure
126 */
127
128 /* try setup reattempt, remember this by setting setup_reattempt_ti */
129 cc_data->setup_reattempt_ti = cc_data->ti;
130 break;
131
132 default: /* Don't try setup reattempt, no appropriate cause */
133 srv_free_stored_setup ();
134 break;
135 }
136 }
137 break;
138
139 default: /* Don't try setup reattempt in other states */
140 break;
141 }
142 }
143
144 /*
145 +--------------------------------------------------------------------+
146 | PROJECT : GSM-PS (6147) MODULE : CC_REL |
147 | STATE : code ROUTINE : cc_setup_reattempt |
148 +--------------------------------------------------------------------+
149
150 PURPOSE : This function reattempts the mobile originated setup
151 for some certain reasons which may indicate network
152 failure. This function is considered as a hack only
153 for networks which tend to deliver a poor quality
154 of service only.
155
156 */
157
158 LOCAL void cc_setup_reattempt (void)
159 {
160 GET_INSTANCE_DATA;
161 TRACE_FUNCTION ("cc_setup_reattempt()");
162
163 if (cc_data->ti EQ cc_data->setup_reattempt_ti)
164 {
165 PALLOC (est, MMCM_ESTABLISH_REQ); /* T_MMCM_ESTABLISH_REQ */
166 est->ti = cc_data->ti;
167 est->estcs = cc_data->estcs;
168 for_est_req (est);
169
170 cc_data->setup_reattempt_ti = NOT_PRESENT_8BIT;
171 cc_data->progress_desc[cc_data->index_ti] = NOT_PRESENT_8BIT;
172 cc_set_state (M_CC_CS_01);
173 TIMERSTART (T303, T303_VALUE);
174 }
175 }
176
177 /*==== VARIABLES ==================================================*/
178
179 /*==== FUNCTIONS ==================================================*/
180 /*
181 +--------------------------------------------------------------------+
182 | PROJECT : GSM-PS (6147) MODULE : CC_REL |
183 | STATE : code ROUTINE : cc_mncc_disconnect_req |
184 +--------------------------------------------------------------------+
185
186 PURPOSE : Disconnection of call by the mobile side.
187
188 */
189
190 GLOBAL void cc_mncc_disconnect_req (T_MNCC_DISCONNECT_REQ * disc)
191 {
192 GET_INSTANCE_DATA;
193 TRACE_FUNCTION ("cc_mncc_disconnect_req()");
194
195 if ((cc_data->index_ti = srv_convert_ti (disc->ti))
196 EQ NOT_PRESENT_8BIT)
197 {
198 PFREE (disc);
199 return;
200 }
201 if (cc_data->ti EQ cc_data->setup_reattempt_ti)
202 {
203 srv_free_stored_setup ();
204 }
205 switch (cc_data->state[cc_data->index_ti])
206 {
207 case M_CC_CS_03: /* WAIT FOR NW. INFO */
208 case M_CC_CS_05: /* CC ESTABLISHMENT CONFIRMED */
209 case M_CC_CS_06: /* RECALL PRESENT */
210 /* Forget stored CCBS setup */
211 if (cc_data->stored_ccbs_setup NEQ NULL)
212 {
213 PFREE (cc_data->stored_ccbs_setup);
214 cc_data->stored_ccbs_setup = NULL;
215 }
216
217 /* Send a (faked) MNCC_RELEASE_IND to MMI */
218 {
219 PALLOC (rel, MNCC_RELEASE_IND);
220 rel->ti = disc->ti;
221 rel->cause = disc->cause;
222 rel->c_raw_cause = 0;
223 PSENDX (MMI, rel);
224 }
225
226 /* Send RELEASE COMPLETE to network */
227 CCD_START;
228 {
229 MCAST (rel_com, U_RELEASE_COMP);
230 cc_build_release_complete (rel_com, disc->cause);
231 for_release_complete (rel_com);
232 }
233 CCD_END;
234
235 /* Release MM connection */
236 for_rel_req ();
237
238 PFREE (disc);
239
240 /* Stop all running timers */
241 TIMERSTOP (TIMER_CC);
242
243 /* Next state is NULL */
244 cc_set_state (M_CC_CS_0);
245 break;
246
247 case M_CC_CS_01:
248 case CS_101:
249 case CS_261:
250 {
251 TIMERSTOP (TIMER_CC);
252
253 cc_reset_dtmf ();
254
255 {
256 PALLOC (rel, MNCC_RELEASE_IND);
257 rel->ti = disc->ti;
258 rel->cause = disc->cause;
259 rel->c_raw_cause = 0;
260 PSENDX (MMI, rel);
261 }
262
263 for_rel_req ();
264 cc_set_state (M_CC_CS_0);
265 srv_use_stored_prim ();
266 PFREE (disc);
267 }
268 break;
269
270 case M_CC_CS_1:
271 case M_CC_CS_3:
272 case M_CC_CS_4:
273 case M_CC_CS_7:
274 case M_CC_CS_8:
275 case M_CC_CS_9:
276 case M_CC_CS_10:
277 case M_CC_CS_26:
278 TIMERSTOP (TIMER_CC);
279
280 CCD_START;
281 {
282 MCAST (disconnect, U_DISCONNECT);
283
284 cc_build_disconnect (disconnect, disc->cause,
285 &disc->fac_inf, disc->ss_version);
286 cc_set_state (M_CC_CS_11);
287 for_disconnect (disconnect);
288 }
289 CCD_END;
290 TIMERSTART (T305, T305_VALUE);
291 PFREE (disc);
292 break;
293
294 case M_CC_CS_12: /* DISCONNECT INDICATION, this is clear collision here */
295 CCD_START;
296 {
297 MCAST (release, U_RELEASE);
298
299 cc_build_release (release, disc->cause,
300 NULL, MNCC_SS_VER_NOT_PRES);
301 cc_set_state (M_CC_CS_19);
302 for_release (release);
303
304 }
305 CCD_END;
306 TIMERSTART (T308, T308_VALUE);
307 PFREE (disc);
308 break;
309
310 default:
311 PFREE (disc);
312 break;
313
314 }
315 }
316 /*
317 +--------------------------------------------------------------------+
318 | PROJECT : GSM-PS (6147) MODULE : CC_REL |
319 | STATE : code ROUTINE : cc_mncc_reject_req |
320 +--------------------------------------------------------------------+
321
322 PURPOSE : Release of call by the mobile side by sending
323 a RELEASE COMPLETE message.
324
325 */
326
327 GLOBAL void cc_mncc_reject_req (T_MNCC_REJECT_REQ * rej)
328 {
329 GET_INSTANCE_DATA;
330
331 TRACE_FUNCTION ("cc_mncc_reject_req");
332
333 if ((cc_data->index_ti = srv_convert_ti (rej->ti))
334 EQ NOT_PRESENT_8BIT)
335 {
336 PFREE (rej);
337 return;
338 }
339
340 if (cc_data->ti EQ cc_data->setup_reattempt_ti)
341 {
342 srv_free_stored_setup ();
343 }
344
345 switch (cc_data->state[cc_data->index_ti])
346 {
347 case M_CC_CS_03: /* WAIT FOR NW. INFO */
348 case M_CC_CS_05: /* CC ESTABLISHMENT CONFIRMED */
349 case M_CC_CS_06: /* RECALL PRESENT */
350 /* Forget stored CCBS setup */
351 if (cc_data->stored_ccbs_setup NEQ NULL)
352 {
353 PFREE (cc_data->stored_ccbs_setup);
354 cc_data->stored_ccbs_setup = NULL;
355 }
356
357 /* Send RELEASE COMPLETE */
358 CCD_START;
359 {
360 MCAST (rel_com, U_RELEASE_COMP);
361 cc_build_release_complete (rel_com, rej->cause);
362 for_release_complete (rel_com);
363 }
364 CCD_END;
365
366 /* Release MM connection */
367 for_rel_req ();
368
369 PFREE (rej);
370
371 /* Stop all running timers */
372 TIMERSTOP (TIMER_CC);
373
374 /* Next state is NULL */
375 cc_set_state (M_CC_CS_0);
376 break;
377 default:
378 PFREE (rej);
379 break;
380 }
381 }
382
383
384 /*
385 +--------------------------------------------------------------------+
386 | PROJECT : GSM-PS (6147) MODULE : CC_REL |
387 | STATE : code ROUTINE : cc_mncc_release_req |
388 +--------------------------------------------------------------------+
389
390 PURPOSE : Release of call by the mobile side.
391
392 */
393 GLOBAL void cc_mncc_release_req (T_MNCC_RELEASE_REQ * rel)
394 {
395 GET_INSTANCE_DATA;
396
397 TRACE_FUNCTION ("cc_mncc_release_req()");
398
399 if ((cc_data->index_ti = srv_convert_ti (rel->ti))
400 EQ NOT_PRESENT_8BIT)
401 {
402 PFREE (rel);
403 return;
404 }
405
406 if (cc_data->ti EQ cc_data->setup_reattempt_ti)
407 {
408 srv_free_stored_setup ();
409 }
410
411 switch (cc_data->state[cc_data->index_ti])
412 {
413 case M_CC_CS_12: /* DISCONNECT INDICATION */
414
415 CCD_START;
416 {
417 MCAST (release, U_RELEASE);
418
419 cc_build_release (release, rel->cause,
420 &rel->fac_inf, rel->ss_version);
421 cc_set_state (M_CC_CS_19);
422 for_release (release);
423
424 }
425 CCD_END;
426 TIMERSTART (T308, T308_VALUE);
427 PFREE (rel);
428 break;
429
430 default:
431 PFREE (rel);
432 break;
433
434 }
435 }
436
437 /*
438 +--------------------------------------------------------------------+
439 | PROJECT : GSM-PS (6147) MODULE : CC_REL |
440 | STATE : code ROUTINE : cc_disconnect |
441 +--------------------------------------------------------------------+
442
443 PURPOSE : Processing an incoming disconnect message.
444
445 */
446
447 GLOBAL void cc_disconnect (T_D_DISCONNECT * disconnect)
448 {
449 GET_INSTANCE_DATA;
450
451 TRACE_FUNCTION ("cc_disconnect()");
452
453 /* The cause is in DISCONNECT a mandatory IE (given intact message) */
454 TRACE_EVENT_P1 ("DISCONNECT cause: %02x", disconnect->cc_cause.cause);
455
456 EM_CC_DISCONNECT_RECEIVED;
457
458 switch (cc_data->state[cc_data->index_ti])
459 {
460 case M_CC_CS_11: /* DISCONNECT REQUEST, this is clear collision here */
461 CCD_END;
462 CCD_START;
463 {
464 MCAST (release, U_RELEASE);
465
466 TIMERSTOP (TIMER_CC);
467 /* PATCH LE 10.04.00
468 * set disconnect collision flag
469 */
470 cc_data->disc_coll [cc_data->index_ti] = TRUE;
471 /* END PATCH LE 10.04.00 */
472
473 switch (cc_data->error)
474 {
475 case M_CC_CAUSE_INVALID_MAND_INFO:
476 case M_CC_CAUSE_COND_INFO_ELEM:
477 cc_build_release (release, CAUSE_MAKE(DEFBY_STD,
478 ORIGSIDE_MS,
479 MNCC_CC_ORIGINATING_ENTITY,
480 cc_data->error),
481 NULL, MNCC_SS_VER_NOT_PRES);
482 cc_set_state (M_CC_CS_19);
483 for_release (release);
484 TIMERSTART (T308, T308_VALUE);
485 break;
486
487 default:
488 if (disconnect->v_progress)
489 {
490 cc_data->progress_desc[cc_data->index_ti] =
491 disconnect->progress.progress_desc;
492 }
493 cc_build_release (release, CAUSE_MAKE(DEFBY_CONDAT,
494 ORIGSIDE_MS,
495 MNCC_CC_ORIGINATING_ENTITY,
496 NOT_PRESENT_8BIT),
497 NULL, MNCC_SS_VER_NOT_PRES);
498 cc_set_state (M_CC_CS_19);
499 for_release (release);
500 TIMERSTART (T308, T308_VALUE);
501 break;
502 }
503 }
504 CCD_END;
505 break;
506
507 case M_CC_CS_12: /* DISCONNECT INDICATION */
508 case M_CC_CS_19: /* RELEASE REQUEST */
509 /* NULL (M_CC_CS_0) is handled by the formatter */
510 CCD_END;
511 /* Implements Measure# 3 and streamline encoding */
512 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
513 break;
514
515 default:
516 /* any "normal" state */
517 TIMERSTOP (TIMER_CC);
518
519 switch (cc_data->error)
520 {
521 case M_CC_CAUSE_INVALID_MAND_INFO:
522 case M_CC_CAUSE_COND_INFO_ELEM:
523 CCD_END;
524 CCD_START;
525 {
526 USHORT curr_cause; /* local variable to avoid repeated CAUSE_MAKEs for the same cause */
527
528 MCAST (release, U_RELEASE);
529 PALLOC (disc_ind, MNCC_DISCONNECT_IND);
530
531 disc_ind->ti = cc_data->ti;
532 curr_cause = CAUSE_MAKE(DEFBY_STD,
533 ORIGSIDE_MS,
534 MNCC_CC_ORIGINATING_ENTITY,
535 cc_data->error);
536 disc_ind->cause = curr_cause;
537 /* Setting raw_cause to empty as this is a local release
538 * of MM connection,CC is not receiving any cause value
539 * from Network
540 */
541 disc_ind->c_raw_cause = 0;
542
543 disc_ind->diagnostic = NOT_PRESENT_8BIT;
544 disc_ind->progress_desc = MNCC_PROG_NOT_PRES;
545 /* CQ 23619: get the ss diagnostic >> */
546 disc_ind->ss_diag = MNCC_SS_DIAG_NOT_PROVIDED;
547 /* CQ 23619 << */
548 PSENDX (MMI, disc_ind);
549
550 /* Patch HM 29-Jan-02 >>> */
551 cc_build_facility_ind (MNCC_FAC_IN_DISCONNECT,
552 disconnect->v_facility, &disconnect->facility);
553 /* Patch HM 29-Jan-02 <<< */
554 cc_build_release (release, cc_data->error,
555 NULL, MNCC_SS_VER_NOT_PRES);
556 cc_set_state (M_CC_CS_19);
557 for_release (release);
558 TIMERSTART (T308, T308_VALUE);
559 }
560 CCD_END;
561 break;
562
563 default:
564 if (disconnect->v_progress)
565 {
566 cc_data->progress_desc[cc_data->index_ti] =
567 disconnect->progress.progress_desc;
568 }
569 cc_check_setup_reattempt (&disconnect->cc_cause);
570
571 if (cc_data->ti NEQ cc_data->setup_reattempt_ti)
572 {
573 /*
574 * We don't perform setup reattempt, so send disconnect to MMI
575 */
576 USHORT curr_cause; /* local variable to avoid repeated CAUSE_MAKEs for the same cause */
577 PALLOC (disc_ind, MNCC_DISCONNECT_IND); /* T_MNCC_DISCONNECT_IND */
578 disc_ind->ti = cc_data->ti;
579 disc_ind->cause = curr_cause = CAUSE_MAKE(DEFBY_STD,
580 ORIGSIDE_NET,
581 MNCC_CC_ORIGINATING_ENTITY,
582 disconnect->cc_cause.cause);
583 disc_ind->c_raw_cause = cc_build_cause (&disconnect->cc_cause,
584 disc_ind->raw_cause);
585 disc_ind->diagnostic = NOT_PRESENT_8BIT;
586
587 if (disconnect->v_progress)
588 disc_ind->progress_desc = disconnect->progress.progress_desc;
589 else
590 disc_ind->progress_desc = MNCC_PROG_NOT_PRES;
591
592 /* Handle CCBS possible flag */
593 if ((cc_data->call_ctrl_cap.pcp NEQ 0) AND
594 (disconnect->v_allowed_actions NEQ 0) AND
595 (disconnect->allowed_actions.ccbs_act EQ M_CC_CCBS_YES))
596 {
597 /* CCBS indicated as possible by the network */
598 disc_ind->diagnostic = MNCC_DIAG_CCBS_POSSIBLE;
599 }
600 /* CQ 23619: get the ss diagnostic */
601 disc_ind->ss_diag = cc_get_ss_diag(curr_cause, disconnect);
602 /* CQ 23619 << */
603 PSENDX (MMI, disc_ind);
604 /* Patch HM 29-Jan-02 >>> */
605 cc_build_facility_ind (MNCC_FAC_IN_DISCONNECT,
606 disconnect->v_facility, &disconnect->facility);
607 /* Patch HM 29-Jan-02 <<< */
608 }
609 if ((cc_data->ti NEQ cc_data->setup_reattempt_ti) AND
610 (((disconnect->v_progress AND
611 (disconnect->progress.progress_desc EQ M_CC_PROG_INBAND_AVAIL) AND
612 (cc_data->channel_mode != NAS_CHM_SIG_ONLY)))
613 OR
614 ((cc_data->call_ctrl_cap.pcp NEQ 0) AND
615 (disconnect->v_allowed_actions NEQ 0) AND
616 (disconnect->allowed_actions.ccbs_act EQ M_CC_CCBS_YES))))
617 {
618 /*
619 * Hook on tone is generated by the
620 * infrastructure and signalled via TCH OR CCBS is possible
621 */
622 CCD_END;
623 cc_set_state (M_CC_CS_12);
624 }
625 else
626 {
627 CCD_END;
628 CCD_START;
629 {
630 MCAST (release, U_RELEASE);
631
632 /*
633 * Hook on tone is generated internally by the mobile station
634 * and no CCBS possible, the connection is released
635 */
636 cc_build_release (release, CAUSE_MAKE(DEFBY_CONDAT,
637 ORIGSIDE_MS,
638 MNCC_CC_ORIGINATING_ENTITY,
639 NOT_PRESENT_8BIT),
640 NULL, MNCC_SS_VER_NOT_PRES);
641 cc_set_state (M_CC_CS_19);
642 for_release (release);
643 TIMERSTART (T308, T308_VALUE);
644 }
645 CCD_END;
646 }
647 break;
648 }
649 break;
650 }
651 }
652
653 /*
654 +--------------------------------------------------------------------+
655 | PROJECT : GSM-PS (6147) MODULE : CC_REL |
656 | STATE : code ROUTINE : cc_release |
657 +--------------------------------------------------------------------+
658
659 PURPOSE : Processing an incoming release message.
660
661 */
662
663 GLOBAL void cc_release (T_D_RELEASE * release)
664 {
665 GET_INSTANCE_DATA;
666
667 TRACE_FUNCTION ("cc_release()");
668
669 if (release->cc_cause.v_cause)
670 {
671 /* The cause is in RELEASE an optional IE */
672 TRACE_EVENT_P1 ("RELEASE cause: %02x", release->cc_cause.cause);
673 }
674 else
675 {
676 TRACE_EVENT ("RELEASE cause: --");
677 }
678
679 switch (cc_data->state[cc_data->index_ti])
680 {
681 /*
682 * M_CC_CS_0 is handled by the formatter
683 */
684 case M_CC_CS_19: /* Release Request */
685 {
686 cc_reset_dtmf ();
687 /* PATCH LE 10.04.00
688 * in disconnect collision case send
689 * MNCC_RELEASE_IND instead of MNCC_RELEASE_CNF
690 .... */
691 TIMERSTOP (TIMER_CC);
692 if (cc_data->disc_coll [cc_data->index_ti])
693 {
694 /* Implements Measure# 8 */
695 cc_mncc_release_ind ((T_PRIM *)D2P(release));
696 }
697 else
698 {
699 /* Implements Measure# 9 */
700 cc_mncc_release_cnf ((T_PRIM *)D2P(release));
701 }
702 // END PATCH LE 10.04.00
703
704 for_rel_req ();
705 cc_set_state (M_CC_CS_0);
706 /* END PATCH LE 10.04.00 */
707 CCD_END;
708 break;
709 }
710
711 case M_CC_CS_1: /* call initiated */
712 case M_CC_CS_3: /* mobile originating call proceeding */
713 cc_check_setup_reattempt (&release->cc_cause);
714 /*FALLTHROUGH*/ /*lint -fallthrough*/
715 default:
716 cc_reset_dtmf (); /* China change HM 11.07.00 */
717 CCD_END;
718 CCD_START;
719 {
720 MCAST (rel_com, U_RELEASE_COMP);
721
722 TIMERSTOP (TIMER_CC);
723 switch (cc_data->error)
724 {
725 case M_CC_CAUSE_INVALID_MAND_INFO:
726 case M_CC_CAUSE_COND_INFO_ELEM:
727 {
728 USHORT curr_cause; /* local variable to avoid repeated CAUSE_MAKEs for the same cause */
729 curr_cause = CAUSE_MAKE(DEFBY_STD,
730 ORIGSIDE_MS,
731 MNCC_CC_ORIGINATING_ENTITY,
732 cc_data->error);
733
734 if (cc_data->ti NEQ cc_data->setup_reattempt_ti)
735 {
736 PALLOC (rel_ind, MNCC_RELEASE_IND);
737 rel_ind->ti = cc_data->ti;
738 rel_ind->cause = curr_cause;
739 rel_ind->c_raw_cause = 0;
740 PSENDX (MMI, rel_ind);
741 }
742 cc_build_release_complete (rel_com, curr_cause);
743 }
744 break;
745
746 default:
747 if (cc_data->ti NEQ cc_data->setup_reattempt_ti)
748 {
749 /* Implements Measure# 8 */
750 cc_mncc_release_ind ((T_PRIM *)D2P(release));
751 }
752 cc_build_release_complete (rel_com, CAUSE_MAKE(DEFBY_CONDAT,
753 ORIGSIDE_MS,
754 MNCC_CC_ORIGINATING_ENTITY,
755 NOT_PRESENT_8BIT));
756 break;
757 }
758
759 for_release_complete (rel_com);
760 }
761 CCD_END;
762 for_rel_req ();
763 cc_set_state (M_CC_CS_0);
764 cc_setup_reattempt ();
765 break;
766 }
767 }
768
769 /*
770 +--------------------------------------------------------------------+
771 | PROJECT : GSM-PS (6147) MODULE : CC_REL |
772 | STATE : code ROUTINE : cc_release_complete |
773 +--------------------------------------------------------------------+
774
775 PURPOSE : Processing an incoming release complete message.
776
777 */
778
779 GLOBAL void cc_release_complete (T_D_RELEASE_COMP * rel_com)
780 {
781 GET_INSTANCE_DATA;
782
783 TRACE_FUNCTION ("cc_release_complete()");
784
785 if (rel_com->cc_cause.v_cause)
786 {
787 /* The cause is in RELEASE COMPLETE an optional IE */
788 TRACE_EVENT_P1 ("RELEASE COMPLETE cause: %02x", rel_com->cc_cause.cause);
789 }
790 else
791 {
792 TRACE_EVENT ("RELEASE COMPLETE cause: --");
793 }
794
795 EM_CC_RELEASE_COMPLETE_RECEIVED;
796
797 switch (cc_data->state[cc_data->index_ti])
798 {
799 case M_CC_CS_0: /* NULL */
800 CCD_END;
801 for_rel_req ();
802 break;
803
804 case M_CC_CS_03: /* WAIT FOR NETWORK INFO*/
805 /* Stop all running CC timers */
806 TIMERSTOP (TIMER_CC);
807
808 /* Inform MMI */
809 {
810 PALLOC (release, MNCC_RELEASE_IND);
811 release->ti = cc_data->ti;
812 if (rel_com->v_cc_cause AND rel_com->cc_cause.v_cause)
813 {
814 release->cause = CAUSE_MAKE(DEFBY_STD,
815 ORIGSIDE_NET,
816 MNCC_CC_ORIGINATING_ENTITY,
817 rel_com->cc_cause.cause);
818 release->c_raw_cause = cc_build_cause (&rel_com->cc_cause,
819 release->raw_cause);
820 }
821 else
822 {
823 release->cause = CAUSE_MAKE(DEFBY_CONDAT,
824 ORIGSIDE_NET,
825 MNCC_CC_ORIGINATING_ENTITY,
826 NOT_PRESENT_8BIT);
827 release->c_raw_cause = 0;
828 }
829 PSENDX (MMI, release);
830 }
831
832 CCD_END;
833
834 /* Release MM connection */
835 for_rel_req ();
836
837 /* Next state is NULL */
838 cc_set_state (M_CC_CS_0);
839 break;
840
841 case M_CC_CS_05: /* CC ESTABLISHMENT CONFIRMED */
842 case M_CC_CS_06: /* RECALL PRESENT */
843 /* Forget stored CCBS setup */
844 PFREE (cc_data->stored_ccbs_setup);
845 cc_data->stored_ccbs_setup = NULL;
846
847 /* Stop all running CC timers */
848 TIMERSTOP (TIMER_CC);
849
850 /* Inform MMI */
851 {
852 PALLOC (release, MNCC_RELEASE_IND);
853 release->ti = cc_data->ti;
854 if (rel_com->v_cc_cause AND rel_com->cc_cause.v_cause)
855 {
856 release->cause = CAUSE_MAKE(DEFBY_STD,
857 ORIGSIDE_NET,
858 MNCC_CC_ORIGINATING_ENTITY,
859 rel_com->cc_cause.cause);
860 release->c_raw_cause = cc_build_cause (&rel_com->cc_cause,
861 release->raw_cause);
862 }
863 else
864 {
865 release->cause = CAUSE_MAKE(DEFBY_CONDAT,
866 ORIGSIDE_NET,
867 MNCC_CC_ORIGINATING_ENTITY,
868 NOT_PRESENT_8BIT);
869 release->c_raw_cause = 0;
870 }
871 PSENDX (MMI, release);
872 }
873
874 CCD_END;
875
876 /* Release MM connection */
877 for_rel_req ();
878
879 /* Next state is NULL */
880 cc_set_state (M_CC_CS_0);
881 break;
882
883 case M_CC_CS_19: /* RELEASE REQUEST */
884 cc_reset_dtmf ();
885 /* PATCH LE 10.04.00
886 * in disconnect collision case send
887 * MNCC_RELEASE_IND instead of MNCC_RELEASE_CNF
888 */
889 TIMERSTOP (TIMER_CC);
890
891 if (cc_data->ti NEQ cc_data->setup_reattempt_ti)
892 {
893 /* Inform MMI only if no setup reattempt for this ti */
894 if (cc_data->disc_coll [cc_data->index_ti])
895 {
896 /* Implements Measure# 9 */
897 cc_mncc_release_ind ((T_PRIM *)D2P(rel_com));
898 }
899 else
900 {
901 /* Implements Measure# 9 */
902 cc_mncc_release_cnf ((T_PRIM *)D2P(rel_com));
903 }
904 /* END PATCH LE 10.04.00 */
905
906 }
907
908 for_rel_req ();
909 cc_set_state (M_CC_CS_0);
910 CCD_END;
911 cc_setup_reattempt ();
912 break;
913
914 case M_CC_CS_1: /* call initiated */
915 case M_CC_CS_3: /* mobile originating call proceeding */
916 cc_check_setup_reattempt (&rel_com->cc_cause);
917 /*FALLTHROUGH*/ /*lint -fallthrough*/
918 default:
919 cc_reset_dtmf (); /* China change HM 11.07.00 */
920 if (cc_data->ti NEQ cc_data->setup_reattempt_ti)
921 {
922 /* Implements Measure# 10 */
923 cc_mncc_release_ind ((T_PRIM *)D2P(rel_com));
924 }
925 for_rel_req ();
926 CCD_END;
927 cc_set_state (M_CC_CS_0);
928 cc_setup_reattempt ();
929 break;
930 }
931 }
932
933 /*
934 +--------------------------------------------------------------------+
935 | PROJECT : GSM-PS (6147) MODULE : CC_REL |
936 | STATE : code ROUTINE : cc_rel_ind |
937 +--------------------------------------------------------------------+
938
939 PURPOSE : Processing of an incoming release indication from
940 mobility management.
941
942 */
943
944 GLOBAL void cc_rel_ind (USHORT cause)
945 {
946 GET_INSTANCE_DATA;
947
948 TRACE_FUNCTION ("cc_rel_ind()");
949
950 switch (cc_data->state[cc_data->index_ti])
951 {
952 case M_CC_CS_0:
953 break;
954
955 case M_CC_CS_05: /* CC ESTABLISHMENT CONFIRMED */
956 case M_CC_CS_06: /* RECALL PRESENT */
957 /* Stop all timers */
958 TIMERSTOP (TIMER_CC);
959
960 /* Forget stored CCBS setup message */
961 PFREE (cc_data->stored_ccbs_setup);
962 cc_data->stored_ccbs_setup = NULL;
963
964 /* Inform MMI */
965 {
966 PALLOC (release, MNCC_RELEASE_IND);
967 release->ti = cc_data->ti;
968 release->cause = cause; /* provide cause from lower layers transparently to higher layers */
969 release->c_raw_cause = 0;
970 PSENDX (MMI, release);
971 }
972
973 cc_set_state (M_CC_CS_0);
974 srv_use_stored_prim ();
975 break;
976
977 case CS_101: /* Re-establishment request in state M_CC_CS_10 */\
978 case CS_261: /* Re-establishment request in state CS_26 */\
979 EM_CC_REESTABLISHED_FAILED;
980 /*FALLTHROUGH*/ /*lint -fallthrough*/
981
982 default:
983 cc_reset_dtmf (); /* China change HM 11.07.00 */
984 if (cc_data->ti NEQ cc_data->setup_reattempt_ti)
985 {
986 PALLOC (rej_ind, MNCC_REJECT_IND);
987 rej_ind->ti = cc_data->ti;
988 rej_ind->cause = cause;
989 PSENDX (MMI, rej_ind);
990 }
991
992 cc_set_state (M_CC_CS_0);
993 if (cc_data->ti EQ cc_data->setup_reattempt_ti)
994 {
995 cc_setup_reattempt();
996 }
997 else
998 {
999 srv_use_stored_prim ();
1000 }
1001 break;
1002 }
1003 }
1004
1005 /*
1006 +--------------------------------------------------------------------+
1007 | PROJECT : GSM-PS (6147) MODULE : CC_REL |
1008 | STATE : code ROUTINE : cc_err_ind |
1009 +--------------------------------------------------------------------+
1010
1011 PURPOSE : Processing of an incoming error indication from
1012 mobility management.
1013
1014 */
1015
1016 GLOBAL void cc_err_ind (T_MMCM_ERROR_IND * err_ind)
1017 {
1018 GET_INSTANCE_DATA;
1019
1020 TRACE_FUNCTION ("cc_err_ind()");
1021
1022 switch (cc_data->state[cc_data->index_ti])
1023 {
1024 case M_CC_CS_0:
1025 break;
1026
1027 case M_CC_CS_10:
1028 {
1029 /* Implements Measure# 41 */
1030 cc_mncc_sync_ind(err_ind->ti, CS_101);
1031
1032 EM_CC_REESTABLISHED_STARTED;
1033
1034 }
1035 break;
1036
1037 case M_CC_CS_26:
1038 {
1039 /* Implements Measure# 41 */
1040 cc_mncc_sync_ind(err_ind->ti, CS_261);
1041
1042 EM_CC_REESTABLISHED_STARTED;
1043
1044 }
1045 break;
1046
1047 default:
1048 cc_reset_dtmf ();
1049 if (cc_data->ti NEQ cc_data->setup_reattempt_ti)
1050 {
1051 PALLOC (rel_ind, MNCC_RELEASE_IND);
1052 rel_ind->cause = err_ind->cause;
1053 rel_ind->ti = cc_data->ti;
1054 rel_ind->c_raw_cause = 0;
1055 PSENDX (MMI, rel_ind);
1056 }
1057 cc_set_state (M_CC_CS_0);
1058 for_rel_req ();
1059 cc_setup_reattempt ();
1060 break;
1061 }
1062 PFREE (err_ind);
1063 }
1064 /* Implements Measure# 8 */
1065 /*
1066 +--------------------------------------------------------------------+
1067 | PROJECT : GSM-PS (6147) MODULE : CC_REL |
1068 | STATE : code ROUTINE : cc_mncc_release_ind |
1069 +--------------------------------------------------------------------+
1070
1071 PURPOSE : send mncc_release_ind
1072
1073 */
1074
1075 LOCAL void cc_mncc_release_ind (T_PRIM * prim)
1076 {
1077 GET_INSTANCE_DATA;
1078 UBYTE v_cc_cause;
1079 T_M_CC_cc_cause *cc_cause;
1080
1081 TRACE_FUNCTION ("cc_mncc_release_ind()");
1082
1083 if (prim->custom.opc EQ D_RELEASE)
1084 {
1085 v_cc_cause = ((T_D_RELEASE *)P2D(prim))->v_cc_cause;
1086 cc_cause = &((T_D_RELEASE *)P2D(prim))->cc_cause;
1087 cc_build_facility_ind (MNCC_FAC_IN_RELEASE,
1088 ((T_D_RELEASE *)P2D(prim))->v_facility,
1089 &((T_D_RELEASE *)P2D(prim))->facility);
1090 }
1091 else
1092 {
1093 v_cc_cause = ((T_D_RELEASE_COMP *)P2D(prim))->v_cc_cause;
1094 cc_cause = &((T_D_RELEASE_COMP *)P2D(prim))->cc_cause;
1095 cc_build_facility_ind (MNCC_FAC_IN_RELEASE_COMP,
1096 ((T_D_RELEASE_COMP *)P2D(prim))->v_facility,
1097 &((T_D_RELEASE_COMP *)P2D(prim))->facility);
1098 }
1099
1100 /* Patch HM 29-Jan-02 <<< */
1101 {
1102 PALLOC (rel_ind, MNCC_RELEASE_IND);
1103 rel_ind->ti = cc_data->ti;
1104 if (v_cc_cause)
1105 {
1106 rel_ind->cause = CAUSE_MAKE(DEFBY_STD,
1107 ORIGSIDE_NET,
1108 MNCC_CC_ORIGINATING_ENTITY,
1109 cc_cause->cause);
1110 rel_ind->c_raw_cause = cc_build_cause (cc_cause,
1111 rel_ind->raw_cause);
1112 }
1113 else
1114 {
1115 rel_ind->cause = CAUSE_MAKE(DEFBY_CONDAT,
1116 ORIGSIDE_NET,
1117 MNCC_CC_ORIGINATING_ENTITY,
1118 NOT_PRESENT_8BIT);
1119 /* Setting raw_cause to empty as this is a local release
1120 * of MM connection,CC is not receiving any cause value
1121 * from Network
1122 */
1123 rel_ind->c_raw_cause = 0;
1124 }
1125 PSENDX (MMI, rel_ind);
1126 }
1127 }
1128
1129 /* Implements Measure# 9 */
1130 /*
1131 +--------------------------------------------------------------------+
1132 | PROJECT : GSM-PS (6147) MODULE : CC_REL |
1133 | STATE : code ROUTINE : cc_mncc_release_cnf |
1134 +--------------------------------------------------------------------+
1135
1136 PURPOSE : send mncc_release_cnf
1137
1138 */
1139
1140 LOCAL void cc_mncc_release_cnf (T_PRIM * prim)
1141 {
1142 GET_INSTANCE_DATA;
1143 UBYTE v_cc_cause;
1144 T_M_CC_cc_cause *cc_cause;
1145
1146 TRACE_FUNCTION ("cc_mncc_release_cnf()");
1147
1148 if (prim->custom.opc EQ D_RELEASE)
1149 {
1150 v_cc_cause = ((T_D_RELEASE *)P2D(prim))->v_cc_cause;
1151 cc_cause = &((T_D_RELEASE *)P2D(prim))->cc_cause;
1152 cc_build_facility_ind (MNCC_FAC_IN_RELEASE_COMP, /* A little bit dirty */
1153 ((T_D_RELEASE *)P2D(prim))->v_facility,
1154 &((T_D_RELEASE *)P2D(prim))->facility);
1155 }
1156 else
1157 {
1158 v_cc_cause = ((T_D_RELEASE_COMP *)P2D(prim))->v_cc_cause;
1159 cc_cause = &((T_D_RELEASE_COMP *)P2D(prim))->cc_cause;
1160 cc_build_facility_ind (MNCC_FAC_IN_RELEASE_COMP,
1161 ((T_D_RELEASE_COMP *)P2D(prim))->v_facility,
1162 &((T_D_RELEASE_COMP *)P2D(prim))->facility);
1163 }
1164
1165 /* Patch HM 29-Jan-02 <<< */
1166 {
1167 PALLOC (rel_cnf, MNCC_RELEASE_CNF);
1168 rel_cnf->ti = cc_data->ti;
1169 if (v_cc_cause)
1170 {
1171 rel_cnf->cause = CAUSE_MAKE(DEFBY_STD,
1172 ORIGSIDE_NET,
1173 MNCC_CC_ORIGINATING_ENTITY,
1174 cc_cause->cause);
1175 rel_cnf->c_raw_cause = cc_build_cause (cc_cause,
1176 rel_cnf->raw_cause);
1177 }
1178 else
1179 {
1180 rel_cnf->cause = CAUSE_MAKE(DEFBY_CONDAT,
1181 ORIGSIDE_NET,
1182 MNCC_CC_ORIGINATING_ENTITY,
1183 NOT_PRESENT_8BIT);
1184 /* Setting raw_cause to empty as this is a local release
1185 * of MM connection,CC is not receiving any cause value
1186 * from Network
1187 */
1188 rel_cnf->c_raw_cause = 0;
1189 }
1190 PSENDX (MMI, rel_cnf);
1191 }
1192 }
1193
1194
1195 /* Implements Measure# 41 */
1196 /*
1197 +--------------------------------------------------------------------+
1198 | PROJECT : GSM-PS (6147) MODULE : CC_REL |
1199 | STATE : code ROUTINE : cc_mncc_sync_ind |
1200 +--------------------------------------------------------------------+
1201
1202 PURPOSE : send cc_mncc_sync_ind
1203
1204 */
1205
1206 LOCAL void cc_mncc_sync_ind (UBYTE ti, UBYTE new_state)
1207 {
1208 TRACE_FUNCTION ("cc_mncc_sync_ind()");
1209 {
1210 PALLOC (sync_ind, MNCC_SYNC_IND); /* T_MNCC_SYNC_IND */
1211
1212 sync_ind->ti = ti;
1213 sync_ind->cause = MNCC_CAUSE_REEST_STARTED;
1214 sync_ind->ch_info.ch_mode=NOT_PRESENT_8BIT;
1215 sync_ind->ch_info.ch_type=NOT_PRESENT_8BIT;
1216
1217 PSENDX (MMI, sync_ind);
1218
1219 for_reest_req ();
1220 cc_set_state (new_state);
1221 }
1222
1223 }
1224 #endif