comparison src/g23m-gsm/cc/cc_est.c @ 1:d393cd9bb723

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