comparison g23m-gsm/cc/cc_est.c @ 0:75a11d740a02

initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 09 Jun 2016 00:02:41 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:75a11d740a02
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GSM-PS (6147)
4 | Modul : CC_EST
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 the establishment
18 | phase of the call control process of the component CC.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef CC_EST_C
23 #define CC_EST_C
24
25 #include "config.h"
26 #include "fixedconf.h"
27 #include "condat-features.h"
28
29 #define ENTITY_CC
30 /*==== INCLUDES ===================================================*/
31
32 #include <string.h>
33 #include "typedefs.h"
34 #include "pcm.h"
35 #include "vsi.h"
36 #include "custom.h"
37 #include "gsm.h"
38 #include "message.h"
39 #include "ccdapi.h"
40 #include "prim.h"
41 #include "cnf_cc.h"
42 #include "mon_cc.h"
43 #include "pei.h"
44 #include "tok.h"
45 #include "cc.h"
46 #include "cc_em.h"
47
48 /*==== EXPORT =====================================================*/
49 /*==== PROTOTYPE ==================================================*/
50 /* Implements Measure# 19 */
51 LOCAL void cc_send_release_cmp (USHORT cause);
52 LOCAL void cc_send_mncc_release_ind (UBYTE ti, USHORT cause);
53 /*==== PRIVAT =====================================================*/
54
55 /*==== VARIABLES ==================================================*/
56
57 /*==== FUNCTIONS ==================================================*/
58
59 /*
60 +--------------------------------------------------------------------+
61 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
62 | STATE : code ROUTINE : cc_init |
63 +--------------------------------------------------------------------+
64
65 PURPOSE : Initialisation of CC data.
66
67 */
68
69 GLOBAL void cc_init (void)
70 {
71 #ifdef OPTION_MULTIPLE_INSTANCES
72
73 USHORT i;
74
75 TRACE_FUNCTION ("cc_init()");
76
77 for (i=0;i<MAX_INSTANCES;i++)
78 cc_init_data (&data_base[i]);
79 }
80 #else
81
82 TRACE_FUNCTION ("cc_init()");
83 cc_init_data ();
84 #endif
85 }
86
87 /*
88 +--------------------------------------------------------------------+
89 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
90 | STATE : code ROUTINE : cc_init_data |
91 +--------------------------------------------------------------------+
92
93 PURPOSE : Initializes the data for one instance.
94
95 */
96
97 GLOBAL void cc_init_data (void)
98 {
99 GET_INSTANCE_DATA;
100 USHORT i;
101
102 TRACE_FUNCTION ("cc_init_data()");
103
104 memset (cc_data, 0, sizeof (T_CC_DATA));
105
106 /* No SETUP / EMERGENCY SETUP pending */
107 cc_data->stored_setup = NULL;
108
109 /* No CCBS SETUP pending */
110 cc_data->stored_ccbs_setup = NULL;
111
112 cc_data->channel_mode = NAS_CHM_SIG_ONLY;
113
114 for (i=0;i<MAX_CC_CALLS;i++)
115 {
116 cc_data->stored_ti_values[i] = NOT_PRESENT_8BIT;
117 }
118
119 cc_csf_ms_cap ();
120
121 /*
122 * Initialise single numbering scheme
123 */
124 cc_data->sns_bcpara.bearer_serv = MNCC_BEARER_SERV_SPEECH;
125 cc_data->sns_mode = MNCC_SNS_MODE_VOICE;
126
127 /*
128 * Initialise connection element for MTC
129 */
130 cc_data->conn_elem = MNCC_CONN_ELEM_NON_TRANS;
131
132 /*
133 * Initialize setup_reattempt_ti to not present
134 */
135 cc_data->setup_reattempt_ti = NOT_PRESENT_8BIT;
136 }
137
138 /*
139 +--------------------------------------------------------------------+
140 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
141 | STATE : code ROUTINE : cc_mncc_configure_req |
142 +--------------------------------------------------------------------+
143
144 PURPOSE : Configuration of bearer capabilities and subaddress
145 by man machine interface.
146
147 */
148
149 static const UBYTE def_modem_type [8] =
150 {
151 MNCC_MT_V21, /* user rate 300 Baud -> modem type V.21 */
152 MNCC_MT_V22, /* user rate 1200 Baud -> modem type V.22 */
153 MNCC_MT_V22_BIS, /* user rate 2400 Baud -> modem type V.22bis */
154 MNCC_MT_V32, /* user rate 4800 Baud -> modem type V32 */
155 MNCC_MT_V32, /* user rate 9600 Baud -> modem type V32 */
156 MNCC_MT_V32, /* 12k transparent, not supported now by ACI */
157 MNCC_MT_V23, /* user rate 12k/75 Baud -> modem type V23 */
158 MNCC_MT_V21, /* user rate 14.4 kBaud -> modem type V21 ??? */
159 };
160
161 GLOBAL void cc_mncc_configure_req (T_MNCC_CONFIGURE_REQ * config)
162 {
163
164 GET_INSTANCE_DATA;
165
166 TRACE_FUNCTION ("cc_mncc_configure_req()");
167
168 /*
169 * store own subadress if available
170 *
171 * NOTE: T_called_party_sub is the wrong type here in MNCC_CONFIGURE_REQ,
172 * this should have been T_calling_party_sub as this is that what
173 * the subaddress is used for in the uplink SETUP message later.
174 * Doesn't really matter here as the types are identical, it's
175 * just somewhat confusing and could be occasionally be changed.
176 */
177 if (config->called_party_sub.c_subaddr)
178 {
179 cc_data->my_party_subaddr.v_tos = TRUE;
180 cc_data->my_party_subaddr.tos = config->called_party_sub.tos;
181 cc_data->my_party_subaddr.v_odd_even = TRUE;
182 cc_data->my_party_subaddr.odd_even = config->called_party_sub.odd_even;
183 cc_data->my_party_subaddr.c_subaddr = config->called_party_sub.c_subaddr;
184 memcpy (cc_data->my_party_subaddr.subaddr,
185 config->called_party_sub.subaddr,
186 config->called_party_sub.c_subaddr);
187 }
188 else
189 memset (&cc_data->my_party_subaddr, 0, sizeof (T_M_CC_called_subaddr));
190 /*
191 * Store CTM support
192 */
193 cc_data->ctm_ena = config->ctm_ena;
194 /*
195 * Store Single Numbering Scheme BC parameter and mode
196 * if available
197 */
198 if (config->sns_mode NEQ NOT_PRESENT_8BIT)
199 {
200 /*
201 * Store Connection Element for MTC
202 * Note that setting conditionally on sns_mode NEQ NOT_PRESENT_8BIT is
203 * possible because ACI always sets sns_mode to something different from
204 * NOT_PRESENT_8BIT when it sends an MNCC_CONFIGURE_REQ.
205 * For future proof use of MNCC_CONFIGURE_REQ (e.g. only subaddress is valid!)
206 * it is convenient and correct to consider parameters only if they
207 * are valid.
208 */
209
210 cc_data->conn_elem = config->bcpara.conn_elem;
211
212 cc_data->sns_mode = config->sns_mode;
213
214 if (cc_data->sns_mode EQ MNCC_SNS_MODE_VOICE)
215 {
216 memset (&cc_data->sns_bcpara, 0 /*NOT_PRESENT_8BIT*/, sizeof (T_MNCC_bcpara));
217 cc_data->sns_bcpara.bearer_serv = (cc_data->ctm_ena EQ MNCC_CTM_ENABLED)?
218 MNCC_BEARER_SERV_SPEECH_CTM: MNCC_BEARER_SERV_SPEECH;
219 }
220 else
221 memcpy (&cc_data->sns_bcpara, &config->bcpara, sizeof (T_MNCC_bcpara));
222 /*
223 * Set modem type to default values for single numbering scheme
224 */
225 switch (cc_data->sns_bcpara.bearer_serv)
226 {
227 case MNCC_BEARER_SERV_FAX:
228 cc_data->sns_bcpara.modem_type = M_CC_MT_NONE;
229 break;
230 case MNCC_BEARER_SERV_SPEECH:
231 case MNCC_BEARER_SERV_AUX_SPEECH:
232 case MNCC_BEARER_SERV_SPEECH_CTM:
233 case MNCC_BEARER_SERV_AUX_SPEECH_CTM:
234 break;
235 default:
236 cc_data->sns_bcpara.modem_type = def_modem_type[config->bcpara.rate-1];
237 if (config->bcpara.modem_type == MNCC_MT_V34)
238 {
239 cc_data->sns_bcpara.modem_type = MNCC_MT_V34;
240 }
241 break;
242 }
243 }
244
245 /*
246 * define connection element if a preferred one is set by MMI
247 */
248 if (cc_data->sns_bcpara.conn_elem EQ MNCC_CONN_ELEM_TRANS_PREF)
249 {
250 /*
251 * check only if transparent asynchronous data services are supported
252 */
253 if (FldGet(cc_data->mscap.datCap1, AsySup))
254 cc_data->sns_bcpara.conn_elem = M_CC_CE_TRANSPA;
255 else
256 cc_data->sns_bcpara.conn_elem = M_CC_CE_RLP;
257 }
258
259 /*
260 * define connection element if a preferred one is set by MMI
261 */
262 if (cc_data->sns_bcpara.conn_elem EQ MNCC_CONN_ELEM_NON_TRANS_PREF)
263 {
264 /*
265 * check only if non-transparent asynchronous data services are supported
266 */
267 if (FldGet (cc_data->mscap.datCap1, RLPSup))
268 cc_data->sns_bcpara.conn_elem = M_CC_CE_RLP;
269 else
270 cc_data->sns_bcpara.conn_elem = M_CC_CE_TRANSPA;
271 }
272
273 PFREE (config);
274 }
275
276 /*
277 +--------------------------------------------------------------------+
278 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
279 | STATE : code ROUTINE : cc_mncc_prompt_rsp |
280 +--------------------------------------------------------------------+
281
282 PURPOSE : A new transaction identifier during network initiated
283 mobile origination call establishment was assigned by
284 upper layers. Under normal conditions this causes the
285 emmission of an MMCC_DATA_REQ (START CC)
286
287 */
288
289 GLOBAL void cc_mncc_prompt_res (T_MNCC_PROMPT_RES * prompt)
290 {
291 GET_INSTANCE_DATA;
292
293 TRACE_FUNCTION ("cc_mncc_prompt_rsp()");
294
295 /* Check parameters */
296 if (prompt->ti >= 7)
297 {
298 /* Invalid transaction identifier */
299 /* Implements Measure# 36, 48 */
300 cc_send_mncc_release_ind (prompt->ti,
301 CAUSE_MAKE(DEFBY_STD,
302 ORIGSIDE_MS,
303 MNCC_CC_ORIGINATING_ENTITY,
304 M_CC_CAUSE_INVALID_TI));
305
306 PFREE (prompt);
307 return;
308 }
309
310 /* Assign ti and allocate a free entry in the call data */
311 cc_data->ti = prompt->ti;
312 cc_data->index_ti = srv_define_ti();
313 if (cc_data->index_ti EQ NOT_PRESENT_8BIT)
314 {
315 /*
316 * No call instance available
317 */
318 /* Implements Measure# 36, 48 */
319 cc_send_mncc_release_ind (prompt->ti, MNCC_CAUSE_MAX_NO_CALLS_REACHED);
320
321 PFREE (prompt);
322 return;
323 }
324
325 /* Send MMCC_PROMPT_RSP */
326 {
327 PALLOC (prompt_rsp, MMCM_PROMPT_RES); // T_MMCM_ESTABLISH_REQ
328 prompt_rsp->ti = prompt->ti;
329 PSENDX (MM, prompt_rsp);
330 }
331
332 /* Send MMCC_DATA_REQ (START CC) */
333
334 CCD_START;
335 {
336 MCAST (start_cc, U_START_CC);
337 cc_build_start_cc (start_cc);
338 for_start_cc (start_cc);
339 }
340 CCD_END;
341
342 /* Start Timer T332 */
343 TIMERSTART (T332, T332_VALUE);
344
345 PFREE (prompt);
346
347 /* Next state is WAIT FOR NETWORK INFO (U0.3) */
348 cc_set_state (M_CC_CS_03);
349 }
350
351 /*
352 +--------------------------------------------------------------------+
353 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
354 | STATE : code ROUTINE : cc_mncc_prompt_rej |
355 +--------------------------------------------------------------------+
356
357 PURPOSE : A new transaction identifier during network initiated
358 mobile origination call establishment could not be
359 assigned by upper layers. MM is informed by
360 MMCC_PROMPT_REJ.
361
362 */
363
364 GLOBAL void cc_mncc_prompt_rej (T_MNCC_PROMPT_REJ * prompt)
365 {
366 TRACE_FUNCTION ("cc_mncc_prompt_rej()");
367
368 PFREE (prompt);
369
370 {
371 PALLOC (reject, MMCM_PROMPT_REJ);
372 PSENDX (MM, reject);
373 }
374 }
375
376
377 /*
378 +--------------------------------------------------------------------+
379 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
380 | STATE : code ROUTINE : cc_mncc_setup_req |
381 +--------------------------------------------------------------------+
382
383 PURPOSE : Starting of mobile originated call.
384
385 */
386
387 GLOBAL void cc_mncc_setup_req (T_MNCC_SETUP_REQ * setup)
388 {
389 GET_INSTANCE_DATA;
390
391 TRACE_FUNCTION ("cc_mncc_setup_req()");
392 cc_data->index_ti = srv_convert_ti (setup->ti);
393 if (cc_data->index_ti NEQ NOT_PRESENT_8BIT)
394 {
395 /*
396 * Transaction identifier already present, this means, we know this ti
397 * and CC is not in M_CC_CS_0 state. This is okay for M_CC_CS_06 (CCBS),
398 * for every other state this is an internal failure.
399 */
400 switch (cc_data->state[cc_data->index_ti])
401 {
402 case M_CC_CS_06: /* RECALL present */
403 /*
404 * Don't use the setup parametes from ACI, instead use
405 * the stored SETUP message in CC.
406 */
407
408 cc_data->progress_desc[cc_data->index_ti] = NOT_PRESENT_8BIT;
409
410 /* No ugly CC setup reattempts here */
411 cc_data->setup_attempts = MAX_SETUP_ATTEMPTS;
412 cc_data->setup_reattempt_ti = NOT_PRESENT_8BIT;
413
414 /* Send stored SETUP message to network and forget it */
415 for_pd (cc_data->stored_ccbs_setup);
416 cc_data->stored_ccbs_setup = NULL;
417
418 /* Set parameters in cc_data */
419 cc_data->call_type [cc_data->index_ti] = CALL_TYPE_MOC;
420
421 /* initialize disconnect collision flag */
422 cc_data->disc_coll [cc_data->index_ti] = FALSE;
423
424 cc_data->t308_counter [cc_data->index_ti] = 0;
425 cc_reset_dtmf ();
426
427 /* Start T303 */
428 TIMERSTART (T303, T303_VALUE);
429
430 /* Next state is CALL INIT */
431 cc_set_state (M_CC_CS_1);
432 break;
433
434 default: /* The ti is already in use and it is not CCBS recall */
435 {
436 PALLOC (rel, MNCC_RELEASE_IND);
437 rel->ti = setup->ti;
438 rel->cause = M_CC_CAUSE_INVALID_TI;
439 rel->c_raw_cause = 0;
440 PSENDX (MMI, rel);
441 }
442 break;
443 }
444 PFREE (setup);
445 return;
446 }
447
448 if (setup->ti >= 7)
449 {
450 /*
451 * Invalid transaction identifier
452 */
453 /* Implements Measure# 36, 48 */
454 cc_send_mncc_release_ind (setup->ti,
455 CAUSE_MAKE(DEFBY_STD,
456 ORIGSIDE_MS,
457 MNCC_CC_ORIGINATING_ENTITY,
458 M_CC_CAUSE_INVALID_TI));
459 PFREE (setup);
460 return;
461 }
462
463 /*
464 * ti is valid here and not already in use
465 */
466 cc_data->ti = setup->ti;
467 cc_data->index_ti = srv_define_ti ();
468 if (cc_data->index_ti EQ NOT_PRESENT_8BIT)
469 {
470 /*
471 * No call instance available
472 */
473 /* Implements Measure# 36, 48 */
474 cc_send_mncc_release_ind (setup->ti, MNCC_CAUSE_MAX_NO_CALLS_REACHED);
475 PFREE (setup);
476 return;
477 }
478
479 /*
480 * Security check: if bcpara indicates not present,
481 * set service to speech
482 */
483 if (setup->bcpara.bearer_serv EQ NOT_PRESENT_8BIT)
484 {
485 setup->bcpara.bearer_serv = (cc_data->ctm_ena EQ MNCC_CTM_ENABLED)?
486 MNCC_BEARER_SERV_SPEECH_CTM: MNCC_BEARER_SERV_SPEECH;
487 }
488 /*
489 * Security check: if prio indicates emergency call,
490 * set service to speech or speech with CTM
491 */
492 if (setup->prio NEQ MNCC_PRIO_NORM_CALL)
493 {
494 switch (setup->bcpara.bearer_serv)
495 {
496 case MNCC_BEARER_SERV_SPEECH:
497 case MNCC_BEARER_SERV_SPEECH_CTM:
498 break;
499 case MNCC_BEARER_SERV_AUX_SPEECH_CTM:
500 setup->bcpara.bearer_serv = MNCC_BEARER_SERV_SPEECH_CTM;
501 break;
502 default:
503 setup->bcpara.bearer_serv = MNCC_BEARER_SERV_SPEECH;
504 break;
505 }
506 }
507
508 if (cc_check_capabilities (&setup->bcpara) EQ FALSE OR
509 cc_check_capabilities ((T_MNCC_bcpara *)&setup->bcpara2) EQ FALSE)
510 {
511 /*
512 * MS doesn't support the requested services.
513 */
514 PALLOC ( rel, MNCC_RELEASE_IND);
515
516 rel->ti = setup->ti;
517 rel->cause = CAUSE_MAKE(DEFBY_STD,
518 ORIGSIDE_MS,
519 MNCC_CC_ORIGINATING_ENTITY,
520 M_CC_CAUSE_BEARER_NOT_IMPLEM);
521 rel->c_raw_cause = 0;
522
523 PSENDX (MMI, rel);
524
525 srv_free_ti ();
526
527 PFREE (setup);
528 }
529 else
530 {
531 PALLOC (est, MMCM_ESTABLISH_REQ); /* T_MMCM_ESTABLISH_REQ */
532 cc_build_bc (&cc_data->bc1, &cc_data->serv1, &setup->bcpara);
533 cc_data->ri = setup->ri;
534 cc_data->bcpara1 = setup->bcpara;
535 memcpy (&cc_data->bcpara2, &setup->bcpara2, sizeof (T_MNCC_bcpara));
536
537 if (cc_data->ri EQ NOT_PRESENT_8BIT)
538 cc_data->serv2 = NOT_PRESENT_8BIT;
539 else
540 cc_build_bc (&cc_data->bc2, &cc_data->serv2, (T_MNCC_bcpara *)&setup->bcpara2);
541 memcpy (&cc_data->bcpara2, &setup->bcpara2, sizeof (T_MNCC_bcpara));
542 est->org_entity = NAS_ORG_ENTITY_CC;
543 est->ti = setup->ti;
544
545 /* Set establ_serv according to chosen bearer capability */
546 switch (cc_data->bcpara1.bearer_serv)
547 {
548 case MNCC_BEARER_SERV_SPEECH:
549 est->estcs = MMCM_ESTCS_MOB_ORIG_SPCH;
550 break;
551
552 case MNCC_BEARER_SERV_ASYNC:
553 if (cc_data->bcpara1.conn_elem == MNCC_CONN_ELEM_TRANS ||
554 cc_data->bcpara1.conn_elem == MNCC_CONN_ELEM_TRANS_PREF)
555 {
556 est->estcs = MMCM_ESTCS_MOB_ORIG_DATA;
557 }
558 else
559 {
560 est->estcs = MMCM_ESTCS_MOB_ORIG_DATA;
561 }
562 break;
563
564 case MNCC_BEARER_SERV_FAX:
565 est->estcs = MMCM_ESTCS_MOB_ORIG_DATA;
566 break;
567
568 default:
569 est->estcs = MMCM_ESTCS_MOB_ORIG_SPCH;
570 break;
571 }
572
573 switch (cc_data->serv1)
574 {
575 case MNCC_SERV_DATA:
576 if (FldGet(cc_data->mscap.datCap2, DHRSup))
577 {
578 /*
579 * Halfrate support for data
580 */
581 switch (setup->bcpara.rate)
582 {
583 case M_CC_UR_0_3_KBIT:
584 case M_CC_UR_1_2_KBIT:
585 case M_CC_UR_2_4_KBIT:
586 case M_CC_UR_4_8_KBIT:
587 case M_CC_UR_1_2_KBIT_V23:
588 est->estcs = MMCM_ESTCS_MOB_ORIG_DATA;
589 break;
590 default:
591 est->estcs = MMCM_ESTCS_MOB_ORIG_DATA;
592 break;
593 }
594 }
595 else
596 est->estcs = MMCM_ESTCS_MOB_ORIG_DATA;
597 break;
598
599 default: /* SERV_SPEECH */
600 if (setup->prio EQ MNCC_PRIO_NORM_CALL)
601 est->estcs = MMCM_ESTCS_MOB_ORIG_SPCH;
602 else
603 est->estcs = MMCM_ESTCS_EMERGE;
604 break;
605 }
606
607 /* Data solely needed for possible redial attempt */
608 cc_data->estcs = est->estcs;
609 cc_data->setup_attempts = 0;
610
611 srv_free_stored_setup ();
612 cc_data->progress_desc[cc_data->index_ti] = NOT_PRESENT_8BIT;
613 cc_data->call_type [cc_data->index_ti] = CALL_TYPE_MOC;
614 // PATCH LE 10.04.00
615 // initialize disconnect collision flag
616 cc_data->disc_coll [cc_data->index_ti] = FALSE;
617 // END PATCH LE 10.04.00
618 cc_data->t308_counter [cc_data->index_ti] = 0;
619 cc_reset_dtmf ();
620
621 CCD_START;
622 if (setup->prio EQ MNCC_PRIO_NORM_CALL)
623 {
624 MCAST (setup_msg, U_SETUP);
625
626 cc_build_setup (setup_msg, setup);
627 for_setup (setup_msg);
628 }
629 else
630 {
631 MCAST (emergency_setup_msg, U_EMERGE_SETUP);
632
633 cc_build_emergency_setup (emergency_setup_msg);
634 for_emergency_setup (emergency_setup_msg);
635 }
636 CCD_END;
637
638 cc_set_state (M_CC_CS_01);
639 for_est_req (est);
640 TIMERSTART (T303, T303_VALUE);
641 PFREE (setup);
642 }
643 }
644
645 /*
646 +--------------------------------------------------------------------+
647 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
648 | STATE : code ROUTINE : cc_mncc_alert_req |
649 +--------------------------------------------------------------------+
650
651 PURPOSE : The mobile side indicates alerting.
652
653 */
654
655 GLOBAL void cc_mncc_alert_req (T_MNCC_ALERT_REQ * alert)
656 {
657 GET_INSTANCE_DATA;
658
659 TRACE_FUNCTION ("cc_mncc_alert_req()");
660
661 if ((cc_data->index_ti = srv_convert_ti (alert->ti))
662 EQ NOT_PRESENT_8BIT)
663 {
664 PFREE (alert);
665 return;
666 }
667
668 switch (cc_data->state[cc_data->index_ti])
669 {
670 case M_CC_CS_9:
671 CCD_START;
672 {
673 MCAST (alert_msg, U_ALERT);
674
675 cc_build_alert (alert_msg);
676 cc_set_state (M_CC_CS_7);
677 for_alert (alert_msg);
678 }
679 CCD_END;
680
681 EM_CC_ALERTING_SENT;
682
683 PFREE (alert);
684 break;
685
686 default:
687 PFREE (alert);
688 break;
689 }
690 }
691
692 /*
693 +--------------------------------------------------------------------+
694 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
695 | STATE : code ROUTINE : cc_mncc_setup_res |
696 +--------------------------------------------------------------------+
697
698 PURPOSE : The mobile side indicates call acceptance.
699
700 */
701
702 GLOBAL void cc_mncc_setup_res (T_MNCC_SETUP_RES * setup_res)
703 {
704 GET_INSTANCE_DATA;
705
706 TRACE_FUNCTION ("cc_mncc_setup_res()");
707
708 if ((cc_data->index_ti = srv_convert_ti (setup_res->ti))
709 EQ NOT_PRESENT_8BIT)
710 {
711 PFREE (setup_res);
712 return;
713 }
714
715 switch (cc_data->state[cc_data->index_ti])
716 {
717 case M_CC_CS_7:
718 case M_CC_CS_9:
719 CCD_START;
720 {
721 MCAST (connect, U_CONNECT);
722 cc_build_connect (connect);
723 cc_set_state (M_CC_CS_8);
724 TIMERSTART (T313, T313_VALUE);
725 for_connect (connect);
726 }
727 CCD_END;
728
729 EM_CC_CONNECT_SENT;
730
731 PFREE (setup_res);
732 break;
733
734 default:
735 PFREE (setup_res);
736 break;
737 }
738 }
739
740
741 /*
742 +--------------------------------------------------------------------+
743 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
744 | STATE : code ROUTINE : cc_alert |
745 +--------------------------------------------------------------------+
746
747 PURPOSE : Processing an incoming alert message.
748
749 */
750
751 GLOBAL void cc_alert (T_D_ALERT * alert)
752 {
753 GET_INSTANCE_DATA;
754 TRACE_FUNCTION ("cc_alert()");
755
756 EM_CC_ALERTING_RECEIVED;
757
758 switch (cc_data->state[cc_data->index_ti])
759 {
760 /*
761 * CS_0 is handled by the formatter
762 */
763 case M_CC_CS_1:
764 case M_CC_CS_3:
765 if (cc_check_error_flag ())
766 {
767 PALLOC (alert_ind, MNCC_ALERT_IND);
768 TIMERSTOP (TIMER_CC);
769
770 if (alert->v_progress)
771 {
772 cc_data->progress_desc[cc_data->index_ti] =
773 alert->progress.progress_desc;
774 }
775
776 cc_build_mncc_alert_ind (alert, alert_ind);
777 PSENDX (MMI, alert_ind);
778
779 cc_build_facility_ind (MNCC_FAC_IN_ALERT, alert->v_facility, &alert->facility);
780 cc_build_user_user_ind (MNCC_USER_IN_ALERT, alert->v_user_user,
781 &alert->user_user);
782 CCD_END;
783 srv_free_stored_setup ();
784 cc_set_state (M_CC_CS_4);
785 }
786 break;
787
788 default:
789 CCD_END;
790 /* Implements Measure# 3 and streamline encoding */
791 cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT);
792 break;
793 }
794 }
795
796 /*
797 +--------------------------------------------------------------------+
798 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
799 | STATE : code ROUTINE : cc_call_proceeding |
800 +--------------------------------------------------------------------+
801
802 PURPOSE : Processing an incoming call proceed message.
803
804 */
805
806 GLOBAL void cc_call_proceeding (T_D_CALL_PROCEED * proceed)
807 {
808 GET_INSTANCE_DATA;
809 TRACE_FUNCTION ("cc_call_proceeding()");
810
811 EM_CC_CALL_PROCEEDING_RECEIVED;
812
813 switch (cc_data->state[cc_data->index_ti])
814 {
815 /*
816 * CS_0 is handled by the formatter
817 */
818 case M_CC_CS_1:
819 if (cc_check_error_flag ())
820 {
821 TIMERSTOP (TIMER_CC); /* timer T303 */
822 if (cc_moc_compatibility (proceed) EQ OKAY)
823 {
824 PALLOC (proceed_ind, MNCC_CALL_PROCEED_IND);
825
826 cc_build_mncc_proceed_ind (proceed, proceed_ind);
827 PSENDX (MMI, proceed_ind);
828
829 cc_build_facility_ind (MNCC_FAC_IN_CALL_PROCEED,
830 proceed->v_facility, &proceed->facility);
831 if (proceed->v_progress)
832 {
833 cc_data->progress_desc[cc_data->index_ti] =
834 proceed->progress.progress_desc;
835 }
836
837 CCD_END;
838 /*
839 * - start T310 unless the CALL PROCEEDING message contains a progress indicator IE
840 * specifying progress description #1, #2, Ph2 handling is not done yet (#64), see
841 * also issue 4967
842 * - start T310 unless a PROGRESS message with #1, 2, 64 has been
843 * received, this is achieved by remembering the progress description in cc_data
844 * - the case when 1. PROGRESS and 2. CALL PROCEEDING with e.g. #4 is handled by
845 * interpreting 5.2.1.1.3 of 04.08 in the manner that a 2nd progress description
846 * superseeds the first one. See also issue 4965 / CC-FIX-4965.
847 */
848 /* start T310 with Ph2 unless progress description value #1, #2 or #64 has been received */
849 {
850 UBYTE prog_desc = cc_data->progress_desc[cc_data->index_ti];
851 if ((prog_desc NEQ MNCC_PROG_NO_END_TO_END_PLMN)
852 AND
853 (prog_desc NEQ MNCC_PROG_DEST_NON_PLMN)
854 AND
855 (prog_desc NEQ MNCC_PROG_QUEUEING))
856 {
857 TIMERSTART (T310, T310_VALUE);
858 }
859 }
860 if (proceed->v_progress AND
861 proceed->progress.v_progress_desc AND
862 proceed->progress.progress_desc EQ M_CC_PROG_INBAND_AVAIL)
863 {
864 /*
865 * Avoid more call establishment attempts if there was
866 * inband announcement heard by the user.
867 * The user should have no way to realize that more than one
868 * call attempt may be taken by CC.
869 */
870 cc_data->setup_attempts = MAX_SETUP_ATTEMPTS;
871 }
872
873 cc_set_state (M_CC_CS_3);
874 }
875 else /* bearer capability check on CALL PROCEEDING failed */
876 {
877 CCD_END;
878 CCD_START;
879 {
880 MCAST (disconnect, U_DISCONNECT);
881 PALLOC (rej_ind, MNCC_REJECT_IND);
882
883 rej_ind->ti = cc_data->ti;
884 /*
885 * GSM 04.08 does not specify what to do / which cause to use;
886 * Condat decided to use normal call clearing with cause #88
887 */
888 rej_ind->cause = CAUSE_MAKE(DEFBY_STD,
889 ORIGSIDE_MS,
890 MNCC_CC_ORIGINATING_ENTITY,
891 MNCC_CAUSE_INCOMPAT_DEST);
892 PSENDX (MMI, rej_ind);
893
894 cc_build_disconnect (disconnect,
895 CAUSE_MAKE(DEFBY_STD,
896 ORIGSIDE_MS,
897 MNCC_CC_ORIGINATING_ENTITY,
898 MNCC_CAUSE_INCOMPAT_DEST),
899 NULL, MNCC_SS_VER_NOT_PRES);
900 cc_set_state (M_CC_CS_11);
901 for_disconnect (disconnect);
902 }
903 CCD_END;
904 TIMERSTART (T305, T305_VALUE);
905 }
906 }
907 break;
908
909 default:
910 CCD_END;
911 /* Implements Measure# 3 and streamline encoding */
912 cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT);
913 break;
914 }
915 }
916
917 /*
918 +--------------------------------------------------------------------+
919 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
920 | STATE : code ROUTINE : cc_connect |
921 +--------------------------------------------------------------------+
922
923 PURPOSE : Processing an incoming connect message.
924
925 */
926
927 GLOBAL void cc_connect (T_D_CONNECT * connect)
928 {
929 GET_INSTANCE_DATA;
930 TRACE_FUNCTION ("cc_connect()");
931
932 switch (cc_data->state[cc_data->index_ti])
933 {
934 /*
935 * CS_0 is handled by the formatter
936 */
937 case M_CC_CS_1:
938 case M_CC_CS_3:
939 case M_CC_CS_4:
940 if (cc_check_error_flag ())
941 {
942 PALLOC (setup_cnf, MNCC_SETUP_CNF);
943
944 TIMERSTOP (TIMER_CC);
945
946 if (connect->v_progress)
947 {
948 cc_data->progress_desc[cc_data->index_ti] =
949 connect->progress.progress_desc;
950 }
951
952 cc_build_mncc_setup_cnf (connect, setup_cnf);
953 PSENDX (MMI, setup_cnf);
954 cc_build_facility_ind (MNCC_FAC_IN_CONNECT, connect->v_facility,
955 &connect->facility);
956 cc_build_user_user_ind (MNCC_USER_IN_CONNECT, connect->v_user_user,
957 &connect->user_user);
958 CCD_END;
959 CCD_START;
960 {
961 MCAST (connect_ack, B_CONNECT_ACK);
962
963 connect_ack->msg_type = B_CONNECT_ACK;
964 for_connect_ack (connect_ack);
965 }
966 CCD_END;
967 srv_free_stored_setup ();
968 cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_IDLE;
969 cc_data->mpty_state[cc_data->index_ti] = M_CC_MPTY_IDLE;
970 cc_set_state (M_CC_CS_10);
971 }
972
973 EM_CC_CONNECT_RECEIVED;
974
975 break;
976
977 default:
978 /* Implements Measure# 3 and streamline encoding */
979 CCD_END;
980 cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT);
981 break;
982 }
983 }
984
985 /*
986 +--------------------------------------------------------------------+
987 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
988 | STATE : code ROUTINE : cc_connect_ack |
989 +--------------------------------------------------------------------+
990
991 PURPOSE : Processing an incoming connect acknowledge message.
992
993 */
994
995 GLOBAL void cc_connect_ack (void)
996 {
997 GET_INSTANCE_DATA;
998 TRACE_FUNCTION ("cc_connect_ack()");
999
1000 switch (cc_data->state[cc_data->index_ti])
1001 {
1002 /*
1003 * CS_0 is handled by the formatter
1004 */
1005 case M_CC_CS_8:
1006 if (cc_check_error_flag ())
1007 {
1008 PALLOC (setup_comp, MNCC_SETUP_COMPL_IND);
1009
1010 CCD_END;
1011
1012 TIMERSTOP (TIMER_CC);
1013
1014 setup_comp->ti = cc_data->ti;
1015 setup_comp->cause = MNCC_CAUSE_SUCCESS;
1016 PSENDX (MMI, setup_comp);
1017
1018 cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_IDLE;
1019 cc_data->mpty_state[cc_data->index_ti] = M_CC_MPTY_IDLE;
1020 cc_set_state (M_CC_CS_10);
1021
1022 EM_CC_CONNECT_ACKNOWLEDGE_RECEIVED;
1023
1024 }
1025 break;
1026
1027 default:
1028 CCD_END;
1029 /* Implements Measure# 3 and streamline encoding */
1030 cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1031 break;
1032 }
1033 }
1034
1035 /*
1036 +--------------------------------------------------------------------+
1037 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
1038 | STATE : code ROUTINE : cc_progress |
1039 +--------------------------------------------------------------------+
1040
1041 PURPOSE : Processing of an incoming progress message.
1042
1043 */
1044
1045 GLOBAL void cc_progress (T_D_PROGRESS * progress)
1046 {
1047 GET_INSTANCE_DATA;
1048
1049 TRACE_FUNCTION ("cc_progress()");
1050
1051 switch (cc_data->state[cc_data->index_ti])
1052 {
1053 /*
1054 * CS_0 is handled by the formatter
1055 */
1056 case M_CC_CS_1:
1057 case M_CC_CS_3:
1058 case M_CC_CS_4:
1059 case M_CC_CS_6:
1060 case M_CC_CS_7:
1061 case M_CC_CS_8:
1062 case M_CC_CS_9:
1063 case M_CC_CS_11:
1064 case M_CC_CS_12:
1065 case M_CC_CS_19:
1066 if (cc_check_error_flag ())
1067 {
1068 PALLOC (progress_ind, MNCC_PROGRESS_IND);
1069
1070 TIMERSTOP (TIMER_CC);
1071
1072 /* Progress indicator IE here is mandatory IE, so no
1073 * checks for presence need to be done here */
1074 cc_data->progress_desc[cc_data->index_ti] =
1075 progress->progress.progress_desc;
1076
1077 cc_build_mncc_progress_ind (progress, progress_ind);
1078 PSENDX (MMI, progress_ind);
1079 cc_build_user_user_ind (MNCC_USER_IN_PROGRESS, progress->v_user_user,
1080 &progress->user_user);
1081 CCD_END;
1082 }
1083
1084 EM_CC_PROGRESS_RECEIVED;
1085
1086 break;
1087
1088 default:
1089 CCD_END;
1090 /* Implements Measure# 3 and streamline encoding */
1091 cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1092 break;
1093 }
1094 }
1095
1096
1097 /*
1098 +--------------------------------------------------------------------+
1099 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
1100 | STATE : code ROUTINE : cc_cc_establishment |
1101 +--------------------------------------------------------------------+
1102
1103 PURPOSE : Processing of an incoming CC ESTABLISHMENT message.
1104 Because the only interesting part in this message
1105 is the setup container, only the decoded SETUP message
1106 is delivered here.
1107
1108 */
1109
1110 GLOBAL void cc_cc_establishment (T_U_SETUP * setup)
1111 {
1112 GET_INSTANCE_DATA;
1113 TRACE_FUNCTION ("cc_cc_establishment()");
1114
1115 switch (cc_data->state[cc_data->index_ti])
1116 {
1117 case M_CC_CS_03: /* WAIT FOR NW INFO */
1118
1119 /* Check errors delivered by formatter */
1120 switch (cc_data->error)
1121 {
1122 case M_CC_CAUSE_INVALID_MAND_INFO:
1123 case M_CC_CAUSE_COND_INFO_ELEM:
1124 CCD_END;
1125 /* Implements Measure# 7 and streamline encoding*/
1126 cc_send_status (cc_data->error);
1127 return;
1128
1129 default: /* No error until now */
1130 /* Stop TIMER T332 */
1131 TIMERSTOP (TIMER_CC);
1132
1133 if (cc_data->stored_ccbs_setup NEQ NULL)
1134 {
1135 /*
1136 * There is only room for one stored CCBS SETUP message
1137 * for all instances. In case this is already occupied,
1138 * the call is released with cause "user busy".
1139 * In this case the CCBS recall is not lost, but suspended
1140 * by the network until the mobile becomes idle.
1141 */
1142 CCD_END;
1143
1144 /* Send RELEASE COMPLETE */
1145 CCD_START;
1146 {
1147 MCAST (rel_com, U_RELEASE_COMP);
1148 cc_build_release_complete (rel_com, CAUSE_MAKE(DEFBY_STD,
1149 ORIGSIDE_MS,
1150 MNCC_CC_ORIGINATING_ENTITY,
1151 MNCC_CAUSE_USER_BUSY));
1152 for_release_complete (rel_com);
1153 }
1154 CCD_END;
1155
1156 /* Inform MMI */
1157 {
1158 PALLOC (release, MNCC_RELEASE_IND);
1159 release->ti = cc_data->ti;
1160 release->cause = MNCC_CAUSE_MAX_NO_RECALLS_REACHED;
1161 release->c_raw_cause = 0;
1162 PSENDX (MMI, release);
1163 }
1164
1165 /* Release MM connection */
1166 for_rel_req ();
1167
1168 /* Next state is NULL */
1169 cc_set_state (M_CC_CS_0);
1170 return;
1171 }
1172
1173 /* Check bearer capabilities, do basic recall alignment */
1174 if (cc_basic_service_align (setup) EQ ERROR)
1175 {
1176 /* Incompatible bearer capabilities. Clear call. */
1177 CCD_END;
1178 /* Implements Measure# 19 */
1179 cc_send_release_cmp (CAUSE_MAKE(DEFBY_STD,
1180 ORIGSIDE_MS,
1181 MNCC_CC_ORIGINATING_ENTITY,
1182 MNCC_CAUSE_INCOMPAT_DEST));
1183 return;
1184 }
1185
1186 /*
1187 * "If the CC Capabilities in the Setup Container IE is different
1188 * to that supported by the mobile station, the mobile station
1189 * shall modify the CC Capabilities in the SETUP message to indicate
1190 * the true capabilities of the mobile station" [GSM 04.08 5.2.3.2]
1191 */
1192 setup->call_ctrl_cap = cc_data->call_ctrl_cap; /* Struct copy */
1193
1194 /*
1195 * Handle facility alignment
1196 * ("Simple recall alignment",
1197 * "Advanced recall alignment" and
1198 * "Recall alignment not essential").
1199 */
1200
1201 /* "Simple recall alignment" handled automatically, do nothing */
1202
1203 if (setup->v_fac_adv)
1204 {
1205 /* Advanced recall alignment not supported. Reject call. */
1206 CCD_END;
1207 /* Implements Measure# 19 */
1208 cc_send_release_cmp (CAUSE_MAKE(DEFBY_STD,
1209 ORIGSIDE_MS,
1210 MNCC_CC_ORIGINATING_ENTITY,
1211 MNCC_CAUSE_FACILITY_REJECT));
1212
1213 return;
1214 }
1215
1216 /*
1217 * The recall alignment not essential facility IE
1218 * need not be handled directly here, it is simply
1219 * an optional IE which was ignored by CCD.
1220 * The only handling we do is to delete the SS-Version
1221 * indicator if there are no remaining facility elements.
1222 */
1223 if (!setup->v_facility)
1224 setup->v_ss_version = FALSE;
1225
1226 /* Store coded setup message in cc_data */
1227 {
1228 /* No assumtions made about length of this foreign message */
1229 PALLOC_SDU (data, MMCM_DATA_REQ, M_CC_L3MAX << 3);
1230 data->sdu.o_buf = CC_ENCODE_OFFSET;
1231 ccd_codeMsg (CCDENT_CC,
1232 UPLINK,
1233 (T_MSGBUF *) &data->sdu,
1234 (UBYTE *) setup,
1235 NOT_PRESENT_8BIT);
1236 cc_data->stored_ccbs_setup = data;
1237 }
1238 CCD_END;
1239
1240 /* Send MMCC_DATA_REQ (CC EST. CONFIRMED) */
1241 CCD_START;
1242 {
1243 MCAST (est_cnf, U_CC_EST_CONF);
1244 if (cc_count_active_connections () EQ 0)
1245 cc_build_cc_est_confirm (est_cnf, CAUSE_MAKE(DEFBY_CONDAT,
1246 ORIGSIDE_MS,
1247 MNCC_CC_ORIGINATING_ENTITY,
1248 NOT_PRESENT_8BIT));
1249 else
1250 cc_build_cc_est_confirm (est_cnf, CAUSE_MAKE(DEFBY_STD,
1251 ORIGSIDE_MS,
1252 MNCC_CC_ORIGINATING_ENTITY,
1253 MNCC_CAUSE_USER_BUSY));
1254 for_cc_est_confirm (est_cnf);
1255 }
1256 CCD_END;
1257
1258 /* Start TIMER T335 */
1259 TIMERSTART (T335, T335_VALUE);
1260
1261 /* Enter the "CC-establishment confirmed" state */
1262 cc_set_state (M_CC_CS_05);
1263 break;
1264 }
1265 break;
1266
1267 default:
1268 /* Message not compatible with protocol state */
1269 CCD_END;
1270
1271 /* Implements Measure# 3 and streamline encoding */
1272 cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1273 break;
1274 }
1275 }
1276
1277 /*
1278 +--------------------------------------------------------------------+
1279 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
1280 | STATE : code ROUTINE : cc_recall |
1281 +--------------------------------------------------------------------+
1282
1283 PURPOSE : Processing of an incoming recall message.
1284
1285 */
1286
1287 GLOBAL void cc_recall (T_D_RECALL * recall)
1288 {
1289 GET_INSTANCE_DATA;
1290
1291 TRACE_FUNCTION ("cc_recall");
1292
1293 switch (cc_data->state[cc_data->index_ti])
1294 {
1295 case M_CC_CS_05: /* CC ESTABLISHMENT CONFIRMED */
1296 switch(cc_data->error)
1297 {
1298 case M_CC_CAUSE_INVALID_MAND_INFO:
1299 case M_CC_CAUSE_COND_INFO_ELEM:
1300 CCD_END;
1301 /* Implements Measure# 7 and streamline encoding*/
1302 cc_send_status (cc_data->error);
1303 return;
1304
1305 default:
1306 /* Stop Timer T335 */
1307 TIMERSTOP (TIMER_CC);
1308 {
1309 T_U_SETUP * setup;
1310 UBYTE result;
1311 PALLOC (fac_ind, MNCC_FACILITY_IND);
1312
1313 /* Process facility element. may be not present */
1314 fac_ind->ti = cc_data->ti;
1315 fac_ind->fac_context = MNCC_FAC_IN_RECALL;
1316 fac_ind->fac_inf.l_fac = recall->facility.c_fac << 3;
1317 fac_ind->fac_inf.o_fac = 0;
1318 memcpy (fac_ind->fac_inf.fac,
1319 recall->facility.fac,
1320 recall->facility.c_fac);
1321
1322 {
1323 PALLOC (rec_ind, MNCC_RECALL_IND); /* T_MNCC_RECALL_IND */
1324
1325 rec_ind->ti = cc_data->ti;
1326 rec_ind->rcl_type = recall->recall_type.rcl_type;
1327 CCD_END;
1328
1329 /*
1330 * Unpack coded setup container.
1331 * Conserving memory, so already processed parameters are
1332 * processed for a second time now. No errors expected.
1333 */
1334 assert (cc_data->stored_ccbs_setup NEQ NULL);
1335 CCD_START;
1336 result = ccd_decodeMsg (CCDENT_CC,
1337 UPLINK,
1338 (T_MSGBUF *) &cc_data->stored_ccbs_setup->sdu,
1339 (UBYTE *) _decodedMsg,
1340 NOT_PRESENT_8BIT);
1341 assert (result EQ ccdOK);
1342 setup = (T_U_SETUP *)_decodedMsg;
1343 result = cc_basic_service_align (setup);
1344 assert (result NEQ ERROR);
1345
1346 /* Process repeat indicator, BC I and BC II */
1347 rec_ind->ri = cc_data->neg_ri;
1348 memcpy (&rec_ind->bcpara, &cc_data->neg_bcpara1,
1349 sizeof (T_MNCC_bcpara));
1350 memcpy (&rec_ind->bcpara2, &cc_data->neg_bcpara2,
1351 sizeof (T_MNCC_bcpara));
1352
1353 /* Process called party address */
1354 rec_ind->called_party.ton = setup->ul_called_num.ton;
1355 rec_ind->called_party.npi = setup->ul_called_num.npi;
1356 rec_ind->called_party.c_called_num = setup->ul_called_num.c_num;
1357 memcpy (rec_ind->called_party.called_num,
1358 setup->ul_called_num.num,
1359 setup->ul_called_num.c_num);
1360
1361 /* Process called party subaddress */
1362 if (setup->v_called_subaddr)
1363 {
1364 rec_ind->called_party_sub.tos =
1365 setup->called_subaddr.tos;
1366 rec_ind->called_party_sub.odd_even =
1367 setup->called_subaddr.odd_even;
1368 rec_ind->called_party_sub.c_subaddr =
1369 setup->called_subaddr.c_subaddr;
1370 memcpy (rec_ind->called_party_sub.subaddr,
1371 setup->called_subaddr.subaddr, MNCC_SUB_LENGTH);
1372 }
1373 else
1374 {
1375 rec_ind->called_party_sub.tos = MNCC_TOS_NOT_PRES;
1376 rec_ind->called_party_sub.c_subaddr = 0;
1377 }
1378 CCD_END;
1379
1380 /* Send MNCC_RECALL_IND */
1381 PSENDX (MMI, rec_ind);
1382 }
1383
1384 /* Handle MNCC_FACILITY_IND */
1385 if (fac_ind->fac_inf.l_fac)
1386 {
1387 PSENDX (MMI, fac_ind);
1388 }
1389 else
1390 PFREE (fac_ind);
1391
1392 /* Next state is RECALL PRESENT */
1393 cc_set_state (M_CC_CS_06);
1394 }
1395 break;
1396 }
1397 break; /* esac CS_05 */
1398 default:
1399 CCD_END;
1400 /* Message not compatible with protocol state */
1401 /* Implements Measure# 3 and streamline encoding*/
1402 cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1403 break;
1404 }
1405 }
1406
1407 /*
1408 +--------------------------------------------------------------------+
1409 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
1410 | STATE : code ROUTINE : cc_setup |
1411 +--------------------------------------------------------------------+
1412
1413 PURPOSE : Processing of an incoming setup message.
1414
1415 */
1416
1417 GLOBAL void cc_setup (T_D_SETUP * setup)
1418 {
1419 GET_INSTANCE_DATA;
1420
1421 TRACE_FUNCTION ("cc_setup()");
1422
1423 switch (cc_data->state[cc_data->index_ti])
1424 {
1425 case M_CC_CS_0:
1426 if (cc_data->ti < 8)
1427 {
1428 /*
1429 * This values are reserved for mobile originated calls.
1430 */
1431 CCD_END;
1432 for_rel_req ();
1433 break;
1434 }
1435
1436 switch (cc_data->error)
1437 {
1438 case M_CC_CAUSE_INVALID_MAND_INFO:
1439 case M_CC_CAUSE_COND_INFO_ELEM:
1440 CCD_END;
1441 CCD_START;
1442 {
1443 MCAST (rel_com, U_RELEASE_COMP);
1444
1445 cc_build_release_complete (rel_com, CAUSE_MAKE(DEFBY_STD,
1446 ORIGSIDE_MS,
1447 MNCC_CC_ORIGINATING_ENTITY,
1448 cc_data->error));
1449 for_release_complete (rel_com);
1450 }
1451 CCD_END;
1452 for_rel_req ();
1453 break;
1454
1455 default:
1456 switch (cc_compatibility_check (setup))
1457 {
1458 case BAD_SUBADDRESS:
1459 CCD_END;
1460 CCD_START;
1461 {
1462 MCAST (rel_com, U_RELEASE_COMP);
1463 cc_build_release_complete (rel_com, CAUSE_MAKE(DEFBY_STD,
1464 ORIGSIDE_MS,
1465 MNCC_CC_ORIGINATING_ENTITY,
1466 MNCC_CAUSE_NO_ROUTE));
1467 for_release_complete (rel_com);
1468 }
1469 CCD_END;
1470 for_rel_req ();
1471 cc_set_state (M_CC_CS_0);
1472 break;
1473
1474 case ERROR:
1475 CCD_END;
1476 CCD_START;
1477 {
1478 MCAST (rel_com, U_RELEASE_COMP);
1479 cc_build_release_complete (rel_com, CAUSE_MAKE(DEFBY_STD,
1480 ORIGSIDE_MS,
1481 MNCC_CC_ORIGINATING_ENTITY,
1482 MNCC_CAUSE_INCOMPAT_DEST));
1483 for_release_complete (rel_com);
1484 }
1485 CCD_END;
1486 for_rel_req ();
1487 cc_set_state (M_CC_CS_0);
1488 break;
1489
1490 case OKAY:
1491 case NEGOTIATION:
1492 {
1493 PALLOC (setup_ind, MNCC_SETUP_IND);
1494
1495 cc_data->progress_desc[cc_data->index_ti] = NOT_PRESENT_8BIT;
1496
1497 if (setup->v_progress)
1498 {
1499 cc_data->progress_desc[cc_data->index_ti] =
1500 setup->progress.progress_desc;
1501 }
1502
1503 cc_data->call_type [cc_data->index_ti] = CALL_TYPE_MTC;
1504 // PATCH LE 10.04.00
1505 // initialize disconnect collision flag
1506 cc_data->disc_coll [cc_data->index_ti] = FALSE;
1507 // END PATCH LE 10.04.00
1508 cc_build_mncc_setup_ind (setup, setup_ind);
1509
1510 PSENDX (MMI, setup_ind);
1511 cc_build_facility_ind (MNCC_FAC_IN_SETUP, setup->v_facility,
1512 &setup->facility);
1513 cc_build_user_user_ind (MNCC_USER_IN_SETUP, setup->v_user_user,
1514 &setup->user_user);
1515
1516
1517
1518 CCD_END;
1519 CCD_START;
1520 {
1521 MCAST (call_cnf, U_CALL_CONF);
1522
1523 if (cc_count_active_connections () EQ 0)
1524 cc_build_call_confirm (call_cnf, CAUSE_MAKE(DEFBY_CONDAT,
1525 ORIGSIDE_MS,
1526 MNCC_CC_ORIGINATING_ENTITY,
1527 NOT_PRESENT_8BIT));
1528 else
1529 cc_build_call_confirm (call_cnf, CAUSE_MAKE(DEFBY_STD,
1530 ORIGSIDE_MS,
1531 MNCC_CC_ORIGINATING_ENTITY,
1532 MNCC_CAUSE_USER_BUSY));
1533 for_call_confirm (call_cnf);
1534 }
1535 CCD_END;
1536 cc_set_state (M_CC_CS_9);
1537
1538 EM_CC_MM_CONNECTION_ESTABLISHED_MT;
1539
1540 break;
1541 }
1542
1543 default:
1544 CCD_END;
1545 break;
1546 }
1547 break;
1548 }
1549 break;
1550
1551 default:
1552 CCD_END;
1553 break;
1554 }
1555 }
1556
1557 /*
1558 +--------------------------------------------------------------------+
1559 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
1560 | STATE : code ROUTINE : cc_sync_ind |
1561 +--------------------------------------------------------------------+
1562
1563 PURPOSE : Processing of an incoming sync indication from
1564 mobility management.
1565
1566 */
1567
1568 GLOBAL void cc_sync_ind (T_MMCM_SYNC_IND * mmcm_sync)
1569 {
1570 GET_INSTANCE_DATA;
1571 PALLOC ( mncc_sync, MNCC_SYNC_IND );
1572
1573 TRACE_FUNCTION ("cc_sync_ind()");
1574
1575
1576 cc_data->channel_type = mmcm_sync->sync_info.ch_info.ch_type;
1577 cc_data->channel_mode = mmcm_sync->sync_info.ch_info.ch_mode;
1578
1579 mncc_sync->ti = mmcm_sync->ti;
1580
1581 mncc_sync->ch_info.ch_mode = mmcm_sync->sync_info.ch_info.ch_mode;
1582 mncc_sync->ch_info.ch_type = mmcm_sync->sync_info.ch_info.ch_type;
1583
1584 mncc_sync->cause = MNCC_CAUSE_CHANNEL_SYNC;
1585 PSENDX (MMI, mncc_sync);
1586 PFREE (mmcm_sync);
1587 }
1588
1589 /*
1590 +--------------------------------------------------------------------+
1591 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
1592 | STATE : code ROUTINE : cc_est_cnf |
1593 +--------------------------------------------------------------------+
1594
1595 PURPOSE : Processing of an incoming establish confirm from
1596 mobility management.
1597
1598 */
1599
1600 GLOBAL void cc_est_cnf (void)
1601 {
1602 GET_INSTANCE_DATA;
1603 TRACE_FUNCTION ("cc_est_cnf()");
1604
1605 switch (cc_data->state[cc_data->index_ti])
1606 {
1607 case M_CC_CS_01:
1608 {
1609 /*
1610 * As CC may potentially do some ugly things like
1611 * MAX_SETUP_ATTEMPTS > 1, we cannot use the stored
1612 * SETUP or EMERGENCY SETUP message, but have to copy.
1613 */
1614 PALLOC_SDU (data, MMCM_DATA_REQ, cc_data->stored_setup->sdu.l_buf);
1615
1616 data->sdu.l_buf = cc_data->stored_setup->sdu.l_buf;
1617 data->sdu.o_buf = cc_data->stored_setup->sdu.o_buf;
1618 memcpy (&data->sdu.buf[data->sdu.o_buf >> 3],
1619 &cc_data->stored_setup->sdu.buf[data->sdu.o_buf >> 3],
1620 data->sdu.l_buf >> 3);
1621
1622 /* Forward the SETUP or EMERGENCY SETUP message to MM */
1623 for_pd (data);
1624 }
1625
1626 cc_set_state (M_CC_CS_1);
1627 srv_use_stored_prim ();
1628 break;
1629
1630 default:
1631 break;
1632 }
1633 }
1634
1635 /*
1636 +--------------------------------------------------------------------+
1637 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
1638 | STATE : code ROUTINE : cc_reest_cnf |
1639 +--------------------------------------------------------------------+
1640
1641 PURPOSE : Processing of an incoming re-establish confirm from
1642 mobility management.
1643
1644 */
1645
1646 GLOBAL void cc_reest_cnf (void)
1647 {
1648 GET_INSTANCE_DATA;
1649
1650 PALLOC (sync, MNCC_SYNC_IND);
1651
1652 TRACE_FUNCTION ("cc_reest_cnf()");
1653
1654 switch (cc_data->state[cc_data->index_ti])
1655 {
1656 case CS_101:
1657 sync->ti = cc_data->ti;
1658 sync->cause = MNCC_CAUSE_REEST_FINISHED;
1659 sync->ch_info.ch_mode = NOT_PRESENT_8BIT;
1660 sync->ch_info.ch_type = NOT_PRESENT_8BIT;
1661 PSENDX (MMI, sync);
1662
1663 cc_set_state (M_CC_CS_10);
1664 srv_use_stored_prim ();
1665 break;
1666
1667 case CS_261:
1668 sync->ti = cc_data->ti;
1669 sync->cause = MNCC_CAUSE_REEST_FINISHED;
1670 sync->ch_info.ch_mode = NOT_PRESENT_8BIT;
1671 sync->ch_info.ch_type = NOT_PRESENT_8BIT;
1672 PSENDX (MMI, sync);
1673
1674 TIMERSTART (T323, T323_VALUE);
1675 cc_set_state (M_CC_CS_26);
1676 srv_use_stored_prim ();
1677 break;
1678
1679 default:
1680 PFREE (sync);
1681 break;
1682 }
1683 }
1684
1685 #ifdef SIM_TOOLKIT
1686 /*
1687 +--------------------------------------------------------------------+
1688 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
1689 | STATE : code ROUTINE : cc_mncc_bearer_cap_req |
1690 +--------------------------------------------------------------------+
1691
1692 PURPOSE: Checks the compatibility of bearer capabilities.
1693 Bearer capabilities in coded form are tranformed to
1694 parameter form and vice versa.
1695 */
1696
1697 GLOBAL void cc_mncc_bearer_cap_req (T_MNCC_BEARER_CAP_REQ * bc_req)
1698 {
1699 PALLOC (bc_conf, MNCC_BEARER_CAP_CNF);
1700
1701 TRACE_FUNCTION ("cc_mncc_bearer_cap_req()");
1702
1703 /* Copy input parameters */
1704 bc_conf->req_id = bc_req->req_id;
1705 bc_conf->bc_mod = bc_req->bc_mod;
1706
1707 /* Set default values to no bcpara to set valid values in case cc_bearer_cap_decode returns OKAY */
1708 memset (&bc_conf->bcpara2, 0, sizeof (T_MNCC_bcpara));
1709 bc_conf->bcpara2.bearer_serv = MNCC_BEARER_SERV_NOT_PRES;
1710
1711 if (bc_req->bc_mod EQ MNCC_BC_MOD_DECODE)
1712 {
1713 /* Transform coded form into parameter form */
1714
1715 /* Copy input parameters */
1716 bc_conf->bcconf = bc_req->bcconf;
1717 bc_conf->bcconf2 = bc_req->bcconf2;
1718
1719 if (cc_bearer_cap_decode(&bc_req->bcconf,
1720 &bc_conf->bcpara)
1721 EQ ERROR)
1722 {
1723 /* Bearer capabilities not supported */
1724 PFREE (bc_req);
1725 bc_conf->cause = CAUSE_MAKE(DEFBY_STD,
1726 ORIGSIDE_MS,
1727 MNCC_CC_ORIGINATING_ENTITY,
1728 MNCC_CAUSE_INCOMPAT_DEST);
1729 PSENDX (MMI, bc_conf);
1730 return;
1731 }
1732
1733 if (cc_bearer_cap_decode((T_MNCC_bcconf *)&bc_req->bcconf2,
1734 (T_MNCC_bcpara *)&bc_conf->bcpara2)
1735 EQ ERROR)
1736 {
1737 /* Bearer capabilities not supported */
1738 PFREE (bc_req);
1739 bc_conf->cause = CAUSE_MAKE(DEFBY_STD,
1740 ORIGSIDE_MS,
1741 MNCC_CC_ORIGINATING_ENTITY,
1742 MNCC_CAUSE_INCOMPAT_DEST);
1743 PSENDX (MMI, bc_conf);
1744 return;
1745 }
1746 }
1747 else
1748 {
1749 /* Transform parameter form into coded form */
1750
1751 /* Copy input parameters */
1752 bc_conf->bcpara = bc_req->bcpara;
1753 bc_conf->bcpara2 = bc_req->bcpara2;
1754
1755 if (cc_bearer_cap_code(&bc_req->bcpara,
1756 &bc_conf->bcconf)
1757 EQ ERROR)
1758 {
1759 /* Bearer capabilities not supported */
1760 PFREE (bc_req);
1761 bc_conf->cause = CAUSE_MAKE(DEFBY_STD,
1762 ORIGSIDE_MS,
1763 MNCC_CC_ORIGINATING_ENTITY,
1764 MNCC_CAUSE_INCOMPAT_DEST);
1765 PSENDX (MMI, bc_conf);
1766 return;
1767 }
1768
1769 if (cc_bearer_cap_code((T_MNCC_bcpara *)&bc_req->bcpara2,
1770 (T_MNCC_bcconf *)&bc_conf->bcconf2)
1771 EQ ERROR)
1772 {
1773 /* Bearer capabilities not supported */
1774 PFREE (bc_req);
1775 bc_conf->cause = CAUSE_MAKE(DEFBY_STD,
1776 ORIGSIDE_MS,
1777 MNCC_CC_ORIGINATING_ENTITY,
1778 MNCC_CAUSE_INCOMPAT_DEST);
1779 PSENDX (MMI, bc_conf);
1780 return;
1781 }
1782 }
1783
1784 bc_conf->cause = MNCC_CAUSE_SUCCESS; /* Positive result */
1785 PSENDX (MMI, bc_conf);
1786 PFREE (bc_req);
1787 }
1788
1789 #endif /*SIM_TOOLKIT */
1790
1791
1792 /* Implements Measure# 3 and streamline encoding*/
1793 /*
1794 +--------------------------------------------------------------------+
1795 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
1796 | STATE : code ROUTINE : cc_send_status |
1797 +--------------------------------------------------------------------+
1798
1799 PURPOSE : Calls CCD Start and then cc_build_and_send_status
1800 for sending status message
1801 */
1802 GLOBAL void cc_send_status (USHORT cause)
1803 {
1804 TRACE_FUNCTION ("cc_send_status()");
1805
1806 CCD_START;
1807 {
1808 MCAST (status, B_STATUS);
1809 cc_build_status (status, CAUSE_MAKE(DEFBY_STD,
1810 ORIGSIDE_MS,
1811 MNCC_CC_ORIGINATING_ENTITY,
1812 cause));
1813 for_status (status);
1814 }
1815 CCD_END;
1816 }
1817
1818 /* Implements Measure# 19 */
1819 /*
1820 +--------------------------------------------------------------------+
1821 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
1822 | STATE : code ROUTINE : cc_send_release_cmp |
1823 +--------------------------------------------------------------------+
1824
1825 PURPOSE : Send release complete message.
1826
1827 */
1828
1829 LOCAL void cc_send_release_cmp (USHORT cause)
1830 {
1831 GET_INSTANCE_DATA;
1832 TRACE_FUNCTION ("cc_send_release_cmp()");
1833
1834 /* Send RELEASE COMPLETE */
1835 CCD_START;
1836 {
1837 MCAST (rel_com, U_RELEASE_COMP);
1838 cc_build_release_complete (rel_com, cause);
1839 for_release_complete (rel_com);
1840 }
1841 CCD_END;
1842
1843 /* Inform MMI */
1844 {
1845 PALLOC (release, MNCC_RELEASE_IND);
1846 release->ti = cc_data->ti;
1847 release->cause = cause;
1848 release->c_raw_cause = cause;
1849 PSENDX (MMI, release);
1850 }
1851
1852 /* Release MM connection */
1853 for_rel_req ();
1854
1855 /* Next state is NULL */
1856 cc_set_state (M_CC_CS_0);
1857
1858 }
1859
1860 /* Implements Measure# 36, 48 */
1861 /*
1862 +--------------------------------------------------------------------------+
1863 | PROJECT : GSM-PS (6147) MODULE : CC_EST |
1864 | STATE : code ROUTINE : cc_send_mncc_release_ind |
1865 +--------------------------------------------------------------------------+
1866
1867 PURPOSE : Send release complete message with cause invalid ti.
1868
1869 */
1870
1871 LOCAL void cc_send_mncc_release_ind(UBYTE ti, USHORT cause)
1872 {
1873 TRACE_FUNCTION ("cc_send_mncc_release_ind");
1874 {
1875 PALLOC (release, MNCC_RELEASE_IND);
1876 release->ti = ti;
1877 release->cause = cause;
1878 release->c_raw_cause = 0;
1879 PSENDX (MMI, release);
1880 }
1881 }
1882 #endif