comparison g23m-gsm/cc/cc_act.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_ACT
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 primitive processing functions
18 | of the SDL process Call Control for the call active
19 | phase of the component CC of the mobile station
20 +-----------------------------------------------------------------------------
21 */
22
23 #ifndef CC_ACT_C
24 #define CC_ACT_C
25
26 #include "config.h"
27 #include "fixedconf.h"
28 #include "condat-features.h"
29
30 #define ENTITY_CC
31 /*==== INCLUDES ===================================================*/
32
33 #include <string.h>
34 #include "typedefs.h"
35 #include "pcm.h"
36 #include "vsi.h"
37 #include "custom.h"
38 #include "gsm.h"
39 #include "message.h"
40 #include "ccdapi.h"
41 #include "prim.h"
42 #include "cnf_cc.h"
43 #include "mon_cc.h"
44 #include "pei.h"
45 #include "tok.h"
46 #include "cc.h"
47 #include "cc_em.h"
48
49 /*==== EXPORT =====================================================*/
50
51 /*==== PROTOTYPES =================================================*/
52 LOCAL void cc_mncc_hold_retrieve_req (T_PRIM * prim);
53
54 /*==== PRIVAT =====================================================*/
55
56 /*==== VARIABLES ==================================================*/
57
58 /*==== FUNCTIONS ==================================================*/
59
60 /*
61 +--------------------------------------------------------------------+
62 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
63 | STATE : code ROUTINE : cc_dtmf_full |
64 +--------------------------------------------------------------------+
65
66 PURPOSE : Check whether DTMF buffer is full
67
68 */
69
70 LOCAL BOOL cc_dtmf_full (const T_DTMF *p_dtmf)
71 {
72 TRACE_FUNCTION ("cc_dtmf_full()");
73
74 return ((p_dtmf->read EQ p_dtmf->write + 1) OR
75 (p_dtmf->read EQ 0 AND p_dtmf->write EQ DTMF_BUF_SIZE - 1));
76 }
77
78
79 /*
80 +--------------------------------------------------------------------+
81 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
82 | STATE : code ROUTINE : cc_dtmf_empty |
83 +--------------------------------------------------------------------+
84
85 PURPOSE : Check whether DTMF buffer is empty
86
87 */
88
89 LOCAL BOOL cc_dtmf_empty (const T_DTMF *p_dtmf)
90 {
91 TRACE_FUNCTION ("cc_dtmf_empty()");
92
93 return (p_dtmf->read EQ p_dtmf->write);
94 }
95
96
97 /*
98 +--------------------------------------------------------------------+
99 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
100 | STATE : code ROUTINE : cc_dtmf_write |
101 +--------------------------------------------------------------------+
102
103 PURPOSE : Write next entry into DTMF buffer.
104 No checks are done (e.g. buffer full)
105
106 */
107
108 LOCAL void cc_dtmf_write (T_DTMF *p_dtmf, UBYTE val)
109 {
110 TRACE_FUNCTION ("cc_dtmf_write()");
111
112 p_dtmf->buf[p_dtmf->write++] = val;
113 if (p_dtmf->write EQ DTMF_BUF_SIZE)
114 p_dtmf->write = 0;
115 }
116
117 /*
118 +--------------------------------------------------------------------+
119 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
120 | STATE : code ROUTINE : cc_dtmf_write |
121 +--------------------------------------------------------------------+
122
123 PURPOSE : Read next entry from DTMF buffer.
124 No checks are done (e.g. buffer empty)
125
126 */
127
128 LOCAL UBYTE cc_dtmf_read (T_DTMF *p_dtmf)
129 {
130 UBYTE val;
131
132 TRACE_FUNCTION ("cc_dtmf_read()");
133
134 val = p_dtmf->buf[p_dtmf->read++];
135 if (p_dtmf->read EQ DTMF_BUF_SIZE)
136 p_dtmf->read = 0;
137 return val;
138 }
139
140
141 /*
142 +--------------------------------------------------------------------+
143 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
144 | STATE : code ROUTINE : cc_dtmf_allowed |
145 +--------------------------------------------------------------------+
146
147 PURPOSE : This functions returns TRUE if DTMF is allowed in the
148 current state, otherwise FALSE.
149
150 */
151
152 LOCAL BOOL cc_dtmf_allowed (void)
153 {
154 GET_INSTANCE_DATA;
155 TRACE_FUNCTION ("cc_dtmf_allowed()");
156
157 /*
158 * "The mobile station shall be capable of transmitting DTMF messages if
159 * and only if the mobile station has the user connection for speech
160 * attached and an appropriate channel is available.
161 *
162 * ".."
163 *
164 * NOTE 1: This specification means that DTMF messages can generally be
165 * sent in the active state of a call in speech transmission
166 * mode or when a traffic channel is available during setup or
167 * release and the progress indicator IE has been received."
168 *
169 * [TS 24.008 subclause 5.5.7]
170 *
171 * As of GSM 04.08 the progress indicator IE can be received by
172 * CALL PROCEEDING, PROGRESS, CONNECT, SETUP, ALERTING and DISCONNECT.
173 */
174 switch (cc_data->state[cc_data->index_ti])
175 {
176 case M_CC_CS_3: /* mobile originating call proceeding */
177 case M_CC_CS_4: /* call delivered */
178 case M_CC_CS_8: /* connect request */
179 case M_CC_CS_11: /* disconnect request */
180 case M_CC_CS_12: /* disconnect indication */
181 case M_CC_CS_19: /* release request */
182 case CS_101: /* substate of CS_10, reestablish requested */
183 case M_CC_CS_26: /* mobile originating modify */
184 case CS_261: /* substate of CS_26, reestablish requested */
185 if (cc_data->progress_desc[cc_data->index_ti] EQ NOT_PRESENT_8BIT)
186 return FALSE; /* Progress indicator IE has not been received */
187 /*FALLTHROUGH*/ /*lint -fallthrough*/
188 case M_CC_CS_10: /* active */
189 if (cc_data->channel_type EQ NAS_CH_SDCCH)
190 return FALSE; /* No TCH assigned */
191
192 if ((cc_data->channel_mode NEQ NAS_CHM_SPEECH) AND
193 (cc_data->channel_mode NEQ NAS_CHM_SPEECH_V2) AND
194 (cc_data->channel_mode NEQ NAS_CHM_SPEECH_V3))
195 return FALSE; /* Channel mode is not speech */
196
197 return TRUE;
198
199 default:
200 return FALSE;
201 }
202 }
203
204 /*==== VARIABLES ==================================================*/
205
206 /*==== FUNCTIONS ==================================================*/
207
208 /*
209 +--------------------------------------------------------------------+
210 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
211 | STATE : code ROUTINE : cc_mncc_start_dtmf_req |
212 +--------------------------------------------------------------------+
213
214 PURPOSE : Sending of DTMF tones to the infrastructure side.
215
216 */
217
218 GLOBAL void cc_mncc_start_dtmf_req (T_MNCC_START_DTMF_REQ * dtmf)
219 {
220 GET_INSTANCE_DATA;
221 T_DTMF * p_dtmf;
222
223 TRACE_FUNCTION ("cc_mncc_start_dtmf_req()");
224
225
226 if ((cc_data->index_ti = srv_convert_ti (dtmf->ti))
227 EQ NOT_PRESENT_8BIT)
228 {
229 PFREE (dtmf);
230 return;
231 }
232
233 switch (cc_data->state[cc_data->index_ti])
234 {
235 default:
236 if (!cc_dtmf_allowed ())
237 {
238 /* Tone dropped. Confirm DTMF request with negative cause */
239 PALLOC (dtmf_cnf, MNCC_START_DTMF_CNF);
240 dtmf_cnf->ti = dtmf->ti;
241 dtmf_cnf->key = dtmf->key;
242 dtmf_cnf->cause = MNCC_CAUSE_DTMF_NOT_ALLOWED;
243 dtmf_cnf->dtmf_mod = dtmf->dtmf_mod;
244 PSENDX (MMI, dtmf_cnf);
245
246 PFREE (dtmf);
247 return;
248 }
249
250 p_dtmf = &cc_data->dtmf [cc_data->index_ti];
251
252 if ( dtmf->dtmf_mod EQ MNCC_DTMF_MOD_AUTO OR
253 dtmf->dtmf_mod EQ MNCC_DTMF_MOD_MAN_START )
254 {
255 if (p_dtmf->state EQ DTMF_IDLE)
256 {
257 /*
258 * If sending of DTMF tones is not in
259 * progress send the tone.
260 */
261 CCD_START;
262 {
263 MCAST (start_dtmf, U_START_DTMF);
264
265 cc_build_start_dtmf (dtmf->key, start_dtmf);
266 for_start_dtmf (start_dtmf);
267 }
268 CCD_END;
269
270 /* On sending a START DTMF message the MS shall start T336 */
271 TIMERSTART (T336, T336_VALUE);
272
273 p_dtmf->state = DTMF_SEND_REQUEST;
274 p_dtmf->mode = (dtmf->dtmf_mod EQ MNCC_DTMF_MOD_AUTO)?DTMF_AUTO:DTMF_MAN;
275 p_dtmf->key = dtmf->key;
276 }
277 else
278 {
279 /*
280 * Not DTMF_IDLE.
281 */
282
283 if (dtmf->dtmf_mod EQ MNCC_DTMF_MOD_AUTO)
284 {
285 /*
286 * If DTMF_MOD_AUTO, store the tone if the buffer is not full.
287 */
288 if (!cc_dtmf_full (p_dtmf))
289 cc_dtmf_write (p_dtmf, (UBYTE)SET_DTMF_MOD(dtmf->key, DTMF_AUTO));
290 // PATCH HM 13.04.00 >>>
291 else
292 {
293 /* Tone dropped. Confirm DTMF request with negative cause */
294 PALLOC (dtmf_cnf, MNCC_START_DTMF_CNF);
295 dtmf_cnf->ti = dtmf->ti;
296 dtmf_cnf->key = dtmf->key;
297 dtmf_cnf->cause = MNCC_CAUSE_DTMF_BUFFER_FULL;
298 dtmf_cnf->dtmf_mod = dtmf->dtmf_mod;
299 PSENDX(MMI, dtmf_cnf);
300 }
301 // PATCH HM 13.04.00 <<<
302 }
303 else
304 {
305 /*
306 * If DTMF_MOD_MAN_START, two conditions have to be fullfilled
307 * that the tone is stored and not dropped:
308 *
309 * - The buffer is not full.
310 * - There is enough room to store the stop which
311 * will follow the tone.
312 */
313 if (!cc_dtmf_full (p_dtmf) AND
314 (p_dtmf->read NEQ (p_dtmf->write + 2) % DTMF_BUF_SIZE))
315 {
316 cc_dtmf_write (p_dtmf, (UBYTE)SET_DTMF_MOD(dtmf->key, DTMF_MAN));
317 }
318 // PATCH HM 13.04.00 >>>
319 else
320 {
321 /* Tone dropped. Confirm DTMF request with negative cause */
322 PALLOC (dtmf_cnf, MNCC_START_DTMF_CNF);
323 dtmf_cnf->ti = dtmf->ti;
324 dtmf_cnf->key = dtmf->key;
325 dtmf_cnf->cause = MNCC_CAUSE_DTMF_BUFFER_FULL;
326 dtmf_cnf->dtmf_mod = dtmf->dtmf_mod;
327 PSENDX (MMI, dtmf_cnf);
328 }
329 // PATCH HM 13.04.00 <<<
330 }
331 }
332 }
333 else
334 {
335 /*
336 * This is DTMF_MOD_MAN_STOP
337 */
338 if ( p_dtmf->state EQ DTMF_SEND_ACKNOWLEDGE AND
339 cc_dtmf_empty (p_dtmf))
340 {
341 /*
342 * If sending of DTMF tones is in
343 * progress stop the tone.
344 */
345 for_stop_dtmf ();
346
347 /* On sending a STOP DTMF message the MS shall start T337 */
348 TIMERSTART (T337, T337_VALUE);
349
350 p_dtmf->state = DTMF_STOP_REQUEST;
351 }
352 else
353 {
354 /*
355 * If DTMF_MOD_MAN_STOP, the stop mark is stored if
356 * the buffer is not full. If DTMF STOP ACK is received
357 * and there are unexpected stops in the buffer due to
358 * a loss of the respective tones, the stops are dropped
359 * until a tone is found.
360 */
361 if (!cc_dtmf_full(p_dtmf))
362 {
363 cc_dtmf_write (p_dtmf, NOT_PRESENT_8BIT);
364 }
365 }
366 }
367 PFREE (dtmf)
368 break;
369
370 case M_CC_CS_26: /* mobile originating modify */
371 case CS_101:
372 case CS_261:
373 srv_store_prim ((T_PRIM *)D2P(dtmf));
374 break;
375 }
376 }
377
378
379 /*
380 +--------------------------------------------------------------------+
381 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
382 | STATE : code ROUTINE : cc_reset_dtmf |
383 +--------------------------------------------------------------------+
384
385 PURPOSE : Reset DTMF machine. If used before CC leaves any state in
386 which DTMF is possible MMI is informed about DTMF failure
387 if there was still a DTMF request outstanding.
388
389 */
390
391 GLOBAL void cc_reset_dtmf (void)
392 {
393 GET_INSTANCE_DATA;
394 T_DTMF * p_dtmf;
395 BOOL dtmf_aborted;
396
397 TRACE_FUNCTION ("cc_reset_dtmf");
398
399 p_dtmf = &cc_data->dtmf[cc_data->index_ti];
400
401 if (cc_dtmf_allowed())
402 {
403 /* Stop all possibly running DTMF timers */
404 TIMERSTOP (TIMER_DTMF);
405
406 /*
407 * A DTMF acknowledge maybe outstanding for ACI either if the
408 * DTMF state is DTMF_SEND_REQ or
409 * a tone was found in the DTMF send buffer
410 */
411 dtmf_aborted = (p_dtmf->state EQ DTMF_SEND_REQUEST);
412 while (!dtmf_aborted AND !cc_dtmf_empty(p_dtmf))
413 dtmf_aborted = (cc_dtmf_read (p_dtmf) NEQ NOT_PRESENT_8BIT);
414
415 if (dtmf_aborted)
416 {
417 /* Tone dropped. Confirm DTMF request with negative cause */
418 PALLOC (dtmf_cnf, MNCC_START_DTMF_CNF);
419 dtmf_cnf->ti = cc_data->ti;
420 dtmf_cnf->key = NOT_PRESENT_8BIT;
421 dtmf_cnf->cause = MNCC_CAUSE_DTMF_ABORTED;
422 dtmf_cnf->dtmf_mod = NOT_PRESENT_8BIT;
423 PSENDX (MMI, dtmf_cnf);
424 }
425
426 }
427 p_dtmf->state = DTMF_IDLE;
428 p_dtmf->write = 0;
429 p_dtmf->read = 0;
430 }
431
432
433 /*
434 +--------------------------------------------------------------------+
435 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
436 | STATE : code ROUTINE : cc_start_dtmf_ack |
437 +--------------------------------------------------------------------+
438
439 PURPOSE : Processing an incoming start dtmf acknowledge message.
440
441 */
442
443 GLOBAL void cc_start_dtmf_ack (T_D_START_DTMF_ACK * start_dtmf_ack)
444 {
445 GET_INSTANCE_DATA;
446 T_DTMF * p_dtmf;
447
448 TRACE_FUNCTION ("cc_start_dtmf_ack()");
449
450 if (cc_dtmf_allowed ())
451 {
452 if (cc_check_error_flag ())
453 {
454 p_dtmf = &cc_data->dtmf[cc_data->index_ti];
455
456 /* Stop T336 */
457 TIMERSTOP (TIMER_DTMF);
458
459 if (p_dtmf->state EQ DTMF_SEND_REQUEST)
460 {
461 PALLOC (start, MNCC_START_DTMF_CNF);
462
463 start->ti = cc_data->ti;
464 start->key = start_dtmf_ack->key_facility.key;
465 start->cause = MNCC_CAUSE_DTMF_START_SUCCESS;
466 start->dtmf_mod = (p_dtmf->mode EQ DTMF_AUTO) ?
467 MNCC_DTMF_MOD_AUTO : MNCC_DTMF_MOD_MAN_START;
468 PSENDX (MMI, start);
469
470 EM_CC_START_DTMF_ACKNOWLEDGE;
471
472 if( p_dtmf->mode EQ DTMF_AUTO )
473 {
474 for_stop_dtmf ();
475
476 /* On sending a STOP DTMF message the MS shall start T337 */
477 TIMERSTART (T337, T337_VALUE);
478
479 p_dtmf->state = DTMF_STOP_REQUEST;
480 }
481 else
482 {
483 /* This is DTMF_MAN */
484 if (!cc_dtmf_empty (p_dtmf))
485 {
486 UBYTE tone;
487
488 tone = cc_dtmf_read (p_dtmf);
489 if (tone EQ NOT_PRESENT_8BIT)
490 {
491 /* Should be always true */
492 p_dtmf->mode = GET_DTMF_MOD(tone);
493 for_stop_dtmf ();
494
495 /* On sending a STOP DTMF message the MS shall start T337 */
496 TIMERSTART (T337, T337_VALUE);
497
498 p_dtmf->state = DTMF_STOP_REQUEST;
499 }
500 while (!cc_dtmf_empty(p_dtmf) AND
501 p_dtmf->buf[p_dtmf->read] EQ NOT_PRESENT_8BIT)
502 {
503 /* Consume all unwanted stop marks */
504 (void)cc_dtmf_read(p_dtmf);
505 }
506 }
507 else
508 p_dtmf->state = DTMF_SEND_ACKNOWLEDGE;
509 }
510 /* Implements Measure# 3 and streamline encoding */
511 CCD_END;
512 }
513 else
514 {
515
516 /* Implements Measure# 3 and streamline encoding */
517 CCD_END;
518 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
519 }
520 /* Implements Measure# 3 and streamline encoding */
521 } /* if (cc_check_error_flag (cc_data)) */
522 } /* if (cc_dtmf_allowed (cc_data)) */
523 else
524 {
525 /*
526 * DTMF not allowed for some reason, e.g. wrong state,
527 * call is not a speech call, no TCH assigned etc.
528 */
529 CCD_END;
530 /* Implements Measure# 3 and streamline encoding */
531 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
532 }
533 }
534
535
536 /*
537 +--------------------------------------------------------------------+
538 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
539 | STATE : code ROUTINE : cc_start_dtmf_rej |
540 +--------------------------------------------------------------------+
541
542 PURPOSE : Processing an incoming start dtmf reject message.
543
544 */
545
546 GLOBAL void cc_start_dtmf_rej (T_D_START_DTMF_REJ * start_dtmf_rej)
547 {
548 GET_INSTANCE_DATA;
549 T_DTMF * p_dtmf;
550
551 TRACE_FUNCTION ("cc_start_dtmf_rej()");
552
553 if (cc_dtmf_allowed ())
554 {
555 if (cc_check_error_flag ())
556 {
557 /* Stop T336 */
558 TIMERSTOP (TIMER_DTMF);
559 p_dtmf = &cc_data->dtmf[cc_data->index_ti];
560 if (p_dtmf->state EQ DTMF_SEND_REQUEST)
561 {
562 PALLOC (start, MNCC_START_DTMF_CNF);
563
564 start->ti = cc_data->ti;
565 start->key = NOT_PRESENT_8BIT;
566 start->dtmf_mod = NOT_PRESENT_8BIT;
567 /*
568 * cause IE is mandatory and the check for presence has been done already
569 * thus there is no need to check for validity of cause IE here anymore
570 */
571 start->cause = CAUSE_MAKE(DEFBY_STD,
572 ORIGSIDE_NET,
573 MNCC_CC_ORIGINATING_ENTITY,
574 start_dtmf_rej->cc_cause.cause);
575 PSENDX (MMI, start);
576
577 p_dtmf->state = DTMF_IDLE;
578 p_dtmf->write = 0;
579 p_dtmf->read = 0;
580 /* Implements Measure# 3 and streamline encoding */
581 CCD_END;
582 }
583 else
584 {
585 /* Implements Measure# 3 and streamline encoding */
586 CCD_END;
587 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
588 }
589 /* Implements Measure# 3 and streamline encoding */
590 }
591 }
592 else
593 {
594 /*
595 * DTMF not allowed for some reason, e.g. wrong state,
596 * call is not a speech call, no TCH assigned etc.
597 */
598 CCD_END;
599 /* Implements Measure# 3 and streamline encoding */
600 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
601 }
602 }
603
604
605 /*
606 +--------------------------------------------------------------------+
607 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
608 | STATE : code ROUTINE : cc_stop_dtmf |
609 +--------------------------------------------------------------------+
610
611 PURPOSE : Stops DTMF, back to DTMF_IDLE state.
612 Reasons for call:
613 1.) Reception of STOP DTMF ACK message
614 2.) Expiry of T336
615 3.) Expiry of T337
616
617 */
618
619 GLOBAL void cc_stop_dtmf (void)
620 {
621 GET_INSTANCE_DATA;
622 T_DTMF * p_dtmf;
623
624 TRACE_FUNCTION ("cc_stop_dtmf()");
625
626 p_dtmf = &cc_data->dtmf[cc_data->index_ti];
627
628 while (!cc_dtmf_empty(p_dtmf))
629 {
630 UBYTE tone;
631
632 tone = cc_dtmf_read (p_dtmf);
633 if (tone NEQ NOT_PRESENT_8BIT)
634 {
635 /*
636 * another DTMF tone has to be sent
637 */
638 p_dtmf->mode = GET_DTMF_MOD (tone);
639 p_dtmf->key = tone & 0x7f;
640 CCD_START;
641 {
642 MCAST (start, U_START_DTMF);
643
644 cc_build_start_dtmf (p_dtmf->key, start);
645 for_start_dtmf (start);
646 }
647 CCD_END;
648
649 /* On sending a START DTMF message the MS shall start T336 */
650 TIMERSTART (T336, T336_VALUE);
651
652 p_dtmf->state = DTMF_SEND_REQUEST;
653 return;
654 }
655 }
656 p_dtmf->state = DTMF_IDLE;
657 srv_use_stored_prim ();
658 }
659
660
661 /*
662 +--------------------------------------------------------------------+
663 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
664 | STATE : code ROUTINE : cc_stop_dtmf_ack |
665 +--------------------------------------------------------------------+
666
667 PURPOSE : Processing an incoming stop dtmf ack message.
668
669 */
670
671 GLOBAL void cc_stop_dtmf_ack (void)
672 {
673 GET_INSTANCE_DATA;
674 T_DTMF * p_dtmf;
675
676 TRACE_FUNCTION ("cc_stop_dtmf_ack()");
677
678 if (cc_dtmf_allowed ())
679 {
680 if (cc_check_error_flag ())
681 {
682 CCD_END;
683 p_dtmf = &cc_data->dtmf[cc_data->index_ti];
684 if (p_dtmf->state EQ DTMF_STOP_REQUEST)
685 {
686 if (p_dtmf->mode EQ DTMF_MAN)
687 {
688 PALLOC (start, MNCC_START_DTMF_CNF);
689 start->ti = cc_data->ti;
690 start->key = NOT_PRESENT_8BIT;
691 start->cause = MNCC_CAUSE_DTMF_STOP_SUCCESS;
692 start->dtmf_mod = MNCC_DTMF_MOD_MAN_STOP;
693 PSENDX (MMI, start);
694 }
695 /* Stop T337 */
696 TIMERSTOP (TIMER_DTMF);
697 cc_stop_dtmf ();
698 }
699 else
700 {
701 /*
702 * The STOP DTMF ACK message was not expected as we did not sent
703 * previously a START DTMF request.
704 */
705 /* Implements Measure# 3 and streamline encoding */
706 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
707 }
708 }
709 }
710 else
711 {
712 /*
713 * DTMF not allowed in the current state
714 */
715 CCD_END;
716 /* Implements Measure# 3 and streamline encoding */
717 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
718 }
719 }
720
721
722 /*
723 +--------------------------------------------------------------------+
724 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
725 | STATE : code ROUTINE : cc_mncc_facility_req |
726 +--------------------------------------------------------------------+
727
728 PURPOSE : Sending of Facility Information by the mobile side.
729
730 */
731
732 GLOBAL void cc_mncc_facility_req (T_MNCC_FACILITY_REQ * facility)
733 {
734 GET_INSTANCE_DATA;
735
736 TRACE_FUNCTION ("cc_mncc_facility_req()");
737
738 if ((cc_data->index_ti = srv_convert_ti (facility->ti))
739 EQ NOT_PRESENT_8BIT)
740 {
741 PFREE (facility);
742 return;
743 }
744
745 switch (cc_data->state[cc_data->index_ti])
746 {
747 case M_CC_CS_19:
748 PFREE (facility);
749 break;
750
751 case M_CC_CS_01:
752 case CS_101:
753 case CS_261:
754 srv_store_prim ((T_PRIM *)D2P(facility));
755 break;
756
757 default:
758 CCD_START;
759 {
760 MCAST (facility_msg, U_FACILITY);
761 cc_build_facility (facility, facility_msg);
762 for_facility (facility_msg);
763
764 EM_CC_FACILITY_TO_THE_NETWORK;
765
766 }
767 CCD_END;
768 PFREE (facility);
769 break;
770 }
771 }
772
773
774 /*
775 +--------------------------------------------------------------------+
776 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
777 | STATE : code ROUTINE : cc_mncc_modify_req |
778 +--------------------------------------------------------------------+
779
780 PURPOSE : Start of a mobile originated in-call modification.
781
782 */
783
784 GLOBAL void cc_mncc_modify_req (T_MNCC_MODIFY_REQ * modify)
785 {
786 GET_INSTANCE_DATA;
787
788 TRACE_FUNCTION ("cc_mncc_modify_req()");
789
790 if ((cc_data->index_ti = srv_convert_ti (modify->ti))
791 EQ NOT_PRESENT_8BIT)
792 {
793 PFREE (modify);
794 return;
795 }
796
797 switch (cc_data->state[cc_data->index_ti])
798 {
799 case M_CC_CS_10:
800 if (((cc_data->hold_state[cc_data->index_ti] EQ M_CC_HLD_IDLE)) AND
801 (cc_data->dtmf[cc_data->index_ti].state EQ DTMF_IDLE))
802 {
803 /*
804 * If no other procedure is running
805 */
806 CCD_START;
807 {
808 MCAST (modify_msg, B_MODIFY);
809 cc_build_modify (modify, modify_msg);
810 for_modify (modify_msg);
811 }
812 CCD_END;
813 PFREE (modify);
814 cc_set_state (M_CC_CS_26);
815 TIMERSTART (T323, T323_VALUE);
816
817 EM_CC_MO_IN_CALL_MODIFICATION;
818
819 }
820 else
821 srv_store_prim ((T_PRIM *)D2P(modify));
822 break;
823
824 default:
825 PFREE (modify);
826 break;
827 }
828 }
829
830
831 /*
832 +--------------------------------------------------------------------+
833 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
834 | STATE : code ROUTINE : cc_mncc_user_req |
835 +--------------------------------------------------------------------+
836
837 PURPOSE : Send user information or congestion control.
838
839 */
840
841 GLOBAL void cc_mncc_user_req (T_MNCC_USER_REQ * user)
842 {
843 GET_INSTANCE_DATA;
844
845 TRACE_FUNCTION ("cc_mncc_user_req()");
846
847 if ((cc_data->index_ti = srv_convert_ti (user->ti))
848 EQ NOT_PRESENT_8BIT)
849 {
850 PFREE (user);
851 return;
852 }
853
854 switch (cc_data->state[cc_data->index_ti])
855 {
856 case M_CC_CS_10:
857 switch (user->congest_lev)
858 {
859 case M_CC_CL_RECEIVER_READY:
860 case M_CC_CL_RECEIVER_NOT_READY:
861 /*
862 * Send Congestion Control
863 */
864 CCD_START;
865 {
866 MCAST (cong_ctrl, B_CONGEST_CTRL);
867
868 cc_build_congestion_control (user, cong_ctrl);
869 for_congestion_control (cong_ctrl);
870 }
871 CCD_END;
872 PFREE (user);
873 break;
874 default:
875 /*
876 * Send User Information
877 */
878 CCD_START;
879 {
880 MCAST (user_msg, B_USER_INFO);
881
882 cc_build_user_information (user, user_msg);
883 for_user_information (user_msg);
884 }
885 CCD_END;
886 PFREE (user);
887 break;
888 }
889 break;
890
891 case CS_101:
892 srv_store_prim ((T_PRIM *)D2P(user));
893 break;
894
895 default:
896 PFREE (user);
897 break;
898 }
899 }
900
901
902 /*
903 +--------------------------------------------------------------------+
904 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
905 | STATE : code ROUTINE : cc_mncc_hold_req |
906 +--------------------------------------------------------------------+
907
908 PURPOSE : Send hold message.
909
910 */
911
912 GLOBAL void cc_mncc_hold_req (T_MNCC_HOLD_REQ * hold)
913 {
914
915 TRACE_FUNCTION ("cc_mncc_hold_req()");
916
917 /* Implements Measure# 18 */
918 cc_mncc_hold_retrieve_req ((T_PRIM *)D2P(hold));
919 }
920
921
922 /*
923 +--------------------------------------------------------------------+
924 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
925 | STATE : code ROUTINE : cc_mncc_retrieve_req |
926 +--------------------------------------------------------------------+
927
928 PURPOSE : Send retrieve message.
929
930 */
931 GLOBAL void cc_mncc_retrieve_req (T_MNCC_RETRIEVE_REQ * retrieve)
932 {
933
934 TRACE_FUNCTION ("cc_mncc_retrieve_req()");
935
936 /* Implements Measure# 18 */
937 cc_mncc_hold_retrieve_req ((T_PRIM *)D2P(retrieve));
938 }
939
940
941 /*
942 +--------------------------------------------------------------------+
943 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
944 | STATE : code ROUTINE : cc_call_is_active |
945 +--------------------------------------------------------------------+
946
947 PURPOSE : Return TRUE if the respective CC instance is in an active
948 state, otherwise return FALSE.
949
950 */
951
952 LOCAL BOOL cc_call_is_active (UBYTE index_ti)
953 {
954 GET_INSTANCE_DATA;
955 TRACE_FUNCTION ("cc_call_is_active()");
956
957 switch (cc_data->state[index_ti])
958 {
959 case M_CC_CS_10:
960 case M_CC_CS_26:
961 case CS_101:
962 case CS_261:
963 return TRUE;
964
965 default:
966 return FALSE;
967 }
968 }
969
970
971 /*
972 +--------------------------------------------------------------------+
973 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
974 | STATE : code ROUTINE : cc_mncc_sync_req |
975 +--------------------------------------------------------------------+
976
977 PURPOSE : Processing a MNCC_SYNC_REQ primitive. To be able to
978 understand some details of this function, see first
979 GSM 03.84, GSM 04.84 and GSM 11.10 chapters 31.4.1 and 31.4.2.
980
981 */
982
983 GLOBAL void cc_mncc_sync_req (T_MNCC_SYNC_REQ * mncc_sync_req)
984 {
985 GET_INSTANCE_DATA;
986 UBYTE i;
987
988 TRACE_FUNCTION ("cc_mncc_sync_req()");
989
990 if ((cc_data->index_ti = srv_convert_ti (mncc_sync_req->ti))
991 EQ NOT_PRESENT_8BIT)
992 {
993 PFREE (mncc_sync_req);
994 return;
995 }
996
997 switch (cc_data->state[cc_data->index_ti])
998 {
999 /*
1000 * Note: MPTY and HOLD only has a meaning in the following states,
1001 * in other states these aux states have absolutely no meaning.
1002 */
1003 case M_CC_CS_10:
1004 case M_CC_CS_26:
1005 case CS_101:
1006 case CS_261:
1007 switch (mncc_sync_req->synccs)
1008 {
1009 case MNCC_SYNCCS_MPTY_EVENT:
1010
1011 TRACE_EVENT_P2 (" ti = %d, mpty_event = %d",
1012 mncc_sync_req->ti,
1013 mncc_sync_req->mpty_event);
1014
1015 switch (mncc_sync_req->mpty_event)
1016 {
1017 case MNCC_MPTY_BUILD_SENT:
1018 for (i = 0; i < MAX_CC_CALLS; i++)
1019 {
1020 if (cc_call_is_active(i) AND
1021 cc_data->mpty_state[i] EQ M_CC_MPTY_IDLE)
1022 {
1023 cc_data->mpty_state[i] = M_CC_MPTY_REQ;
1024 }
1025 }
1026 break;
1027
1028 case MNCC_MPTY_BUILD_FAIL:
1029 for (i = 0; i < MAX_CC_CALLS; i++)
1030 {
1031 if (cc_call_is_active(i) AND
1032 cc_data->mpty_state[i] EQ M_CC_MPTY_REQ)
1033 {
1034 cc_data->mpty_state[i] = M_CC_MPTY_IDLE;
1035 }
1036 }
1037 break;
1038
1039 case MNCC_MPTY_BUILD_SUCCESS:
1040 for (i = 0; i < MAX_CC_CALLS; i++)
1041 {
1042 if (cc_call_is_active(i))
1043 {
1044 cc_data->mpty_state[i] = M_CC_MPTY_CALL;
1045 cc_data->hold_state[i] = M_CC_HLD_IDLE;
1046 }
1047 }
1048 break;
1049
1050 /* -- */
1051
1052 case MNCC_MPTY_SPLIT_SENT:
1053 if (cc_data->mpty_state[cc_data->index_ti] EQ M_CC_MPTY_CALL)
1054 {
1055 cc_data->mpty_state[cc_data->index_ti] = M_CC_MPTY_SPLIT;
1056 }
1057 break;
1058
1059 case MNCC_MPTY_SPLIT_FAIL:
1060 if (cc_data->mpty_state[cc_data->index_ti] EQ M_CC_MPTY_SPLIT)
1061 {
1062 cc_data->mpty_state[cc_data->index_ti] = M_CC_MPTY_CALL;
1063 }
1064 break;
1065
1066 case MNCC_MPTY_SPLIT_SUCCESS:
1067 cc_data->mpty_state[cc_data->index_ti] = M_CC_MPTY_IDLE;
1068 cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_IDLE;
1069 for (i = 0; i < MAX_CC_CALLS; i++)
1070 {
1071 if (cc_call_is_active(i) AND
1072 cc_data->mpty_state[i] NEQ M_CC_MPTY_IDLE)
1073 {
1074 cc_data->hold_state[i] = M_CC_HLD_CALL_HELD;
1075 }
1076 }
1077 break;
1078
1079 /* -- */
1080
1081 case MNCC_MPTY_HOLD_SENT:
1082 for (i = 0; i < MAX_CC_CALLS; i++)
1083 {
1084 if (cc_call_is_active(i) AND
1085 cc_data->mpty_state[i] NEQ M_CC_MPTY_IDLE)
1086 {
1087 cc_data->hold_state[i] = M_CC_HLD_HOLD_REQ;
1088 }
1089 }
1090 break;
1091
1092 case MNCC_MPTY_HOLD_FAIL:
1093 for (i = 0; i < MAX_CC_CALLS; i++)
1094 {
1095 if (cc_call_is_active(i) AND
1096 cc_data->mpty_state[i] NEQ M_CC_MPTY_IDLE)
1097 {
1098 cc_data->hold_state[i] = M_CC_HLD_IDLE;
1099 }
1100 }
1101 break;
1102
1103 case MNCC_MPTY_HOLD_SUCCESS:
1104 for (i = 0; i < MAX_CC_CALLS; i++)
1105 {
1106 if (cc_call_is_active(i) AND
1107 cc_data->mpty_state[i] NEQ M_CC_MPTY_IDLE)
1108 {
1109 cc_data->hold_state[i] = M_CC_HLD_CALL_HELD;
1110 }
1111 }
1112 break;
1113
1114 /* -- */
1115
1116 case MNCC_MPTY_RETRIEVE_SENT:
1117 for (i = 0; i < MAX_CC_CALLS; i++)
1118 {
1119 if (cc_call_is_active(i) AND
1120 cc_data->mpty_state[i] NEQ M_CC_MPTY_IDLE)
1121 {
1122 cc_data->hold_state[i] = M_CC_HLD_RETRIEVE_REQ;
1123 }
1124 }
1125 break;
1126
1127 case MNCC_MPTY_RETRIEVE_FAIL:
1128 for (i = 0; i < MAX_CC_CALLS; i++)
1129 {
1130 if (cc_call_is_active(i) AND
1131 cc_data->mpty_state[i] NEQ M_CC_MPTY_IDLE)
1132 {
1133 cc_data->hold_state[i] = M_CC_HLD_CALL_HELD;
1134 }
1135 }
1136 break;
1137
1138 case MNCC_MPTY_RETRIEVE_SUCCESS:
1139 for (i = 0; i < MAX_CC_CALLS; i++)
1140 {
1141 if (cc_call_is_active(i) AND
1142 cc_data->mpty_state[i] NEQ M_CC_MPTY_IDLE)
1143 {
1144 cc_data->hold_state[i] = M_CC_HLD_IDLE;
1145 }
1146 }
1147 break;
1148
1149 /* -- */
1150
1151 default:
1152 TRACE_ERROR ("Illegal MPTY event");
1153 break;
1154 } /* switch (mncc_sync_req->mpty_event) */
1155 break;
1156
1157 default:
1158 TRACE_ERROR ("Illegal SYNCCS");
1159 } /* switch (mncc_sync_req->synccs) */
1160 break;
1161
1162 default:
1163 break; /* Ignore the event */
1164 } /* switch (cc_data->state[cc_data->index_ti]) */
1165
1166 #ifndef NTRACE
1167 for (i = 0; i < MAX_CC_CALLS; i++)
1168 {
1169 if (cc_call_is_active(i))
1170 {
1171 TRACE_EVENT_P4 (" hold[%d] = %d, mpty[%d] = %d",
1172 cc_data->stored_ti_values[i],
1173 cc_data->hold_state[i],
1174 cc_data->stored_ti_values[i],
1175 cc_data->mpty_state[i]);
1176 }
1177 }
1178 #endif /* #ifndef NTRACE */
1179
1180 PFREE (mncc_sync_req);
1181 }
1182
1183
1184 /*
1185 +--------------------------------------------------------------------+
1186 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
1187 | STATE : code ROUTINE : cc_mncc_status_res |
1188 +--------------------------------------------------------------------+
1189
1190 PURPOSE : Processing a MNCC_STATUS_RES primitive. There is an
1191 outstanding STATUS message which still has to be sent to
1192 the network after having received a STATUS ENQUIRY in U10.
1193
1194 */
1195
1196 GLOBAL void cc_mncc_status_res (T_MNCC_STATUS_RES * mncc_status_res)
1197 {
1198 GET_INSTANCE_DATA;
1199
1200 TRACE_FUNCTION ("cc_mncc_status_res()");
1201
1202 if ((cc_data->index_ti = srv_convert_ti (mncc_status_res->ti))
1203 EQ NOT_PRESENT_8BIT)
1204 {
1205 PFREE (mncc_status_res);
1206 return;
1207 }
1208
1209 switch (cc_data->state[cc_data->index_ti])
1210 {
1211 case M_CC_CS_01: /* MM connection pending */
1212 case CS_101: /* No network connection, reestablishment in progress */
1213 case CS_261:
1214 break;
1215
1216 default:
1217 /* Implements Measure# 3 and streamline encoding */
1218 cc_send_status (M_CC_CAUSE_STATUS_ENQUIRY);
1219 break;
1220 }
1221
1222 PFREE (mncc_status_res);
1223 }
1224
1225
1226 /*
1227 +--------------------------------------------------------------------+
1228 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
1229 | STATE : code ROUTINE : cc_facility |
1230 +--------------------------------------------------------------------+
1231
1232 PURPOSE : Processing of an incoming facility message.
1233
1234 */
1235
1236 GLOBAL void cc_facility (T_D_FACILITY * facility)
1237 {
1238 GET_INSTANCE_DATA;
1239 TRACE_FUNCTION ("cc_facility()");
1240
1241 /*
1242 * A facility message can be received in every state where CC has a
1243 * MM connection, no need to check states here.
1244 */
1245 if (cc_check_error_flag ())
1246 {
1247 cc_build_facility_ind (MNCC_FAC_IN_FACILITY, TRUE, &facility->facility);
1248 CCD_END;
1249 }
1250
1251 EM_CC_FACILITY_FROM_THE_NETWORK;
1252
1253 }
1254
1255
1256 /*
1257 +--------------------------------------------------------------------+
1258 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
1259 | STATE : code ROUTINE : cc_hold_ack |
1260 +--------------------------------------------------------------------+
1261
1262 PURPOSE : Processing an incoming hold ack message.
1263
1264 */
1265
1266 GLOBAL void cc_hold_ack (void)
1267 {
1268 GET_INSTANCE_DATA;
1269 CCD_END;
1270
1271 TRACE_FUNCTION ("cc_hold_ack()");
1272
1273 switch (cc_data->state[cc_data->index_ti])
1274 {
1275 /*
1276 * CS_0 is handled by the formatter
1277 */
1278 case M_CC_CS_10:
1279 if (cc_check_error_flag ())
1280 {
1281 if (cc_data->hold_state[cc_data->index_ti] EQ M_CC_HLD_HOLD_REQ)
1282 {
1283 PALLOC (hold_cnf, MNCC_HOLD_CNF);
1284
1285 cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_CALL_HELD;
1286 hold_cnf->ti = cc_data->ti;
1287 hold_cnf->cause = MNCC_CAUSE_HOLD_SUCCESS;
1288 PSENDX (MMI, hold_cnf);
1289
1290 EM_CC_CALL_HOLD_ACKNOWLEDGE;
1291
1292 }
1293 else
1294 {
1295 /* Implements Measure# 3 and streamline encoding */
1296 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1297 }
1298 }
1299 break;
1300
1301 default:
1302 /* Implements Measure# 3 and streamline encoding */
1303 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1304 break;
1305 }
1306 }
1307
1308 /*
1309 +--------------------------------------------------------------------+
1310 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
1311 | STATE : code ROUTINE : cc_hold_rej |
1312 +--------------------------------------------------------------------+
1313
1314 PURPOSE : Processing an incoming hold rej message.
1315
1316 */
1317
1318 GLOBAL void cc_hold_rej (T_D_HOLD_REJ * hold_rej)
1319 {
1320 GET_INSTANCE_DATA;
1321 TRACE_FUNCTION ("cc_hold_rej()");
1322
1323 switch (cc_data->state[cc_data->index_ti])
1324 {
1325 /*
1326 * CS_0 is handled by the formatter
1327 */
1328 case M_CC_CS_10:
1329 if (cc_data->hold_state[cc_data->index_ti] EQ M_CC_HLD_HOLD_REQ)
1330 {
1331 PALLOC (hold_cnf, MNCC_HOLD_CNF);
1332
1333 cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_IDLE;
1334 hold_cnf->ti = cc_data->ti;
1335
1336 /*
1337 * It is possible for the network to send a REJ without a Cause IE.
1338 * This causes the decoder to flag a Madatory IE error. According to
1339 * 04.08 Sec: 8.5.3.e, the REJ should still be managed as if a correctly
1340 * formatted REJ had been received.
1341 */
1342 if (!hold_rej->cc_cause.v_cause)
1343 {
1344 hold_cnf->cause = MNCC_CAUSE_NO_NET_CAUSE;
1345 }
1346 else
1347 {
1348 hold_cnf->cause = CAUSE_MAKE(DEFBY_STD,
1349 ORIGSIDE_NET,
1350 MNCC_CC_ORIGINATING_ENTITY,
1351 hold_rej->cc_cause.cause);
1352 }
1353 PSENDX (MMI, hold_cnf);
1354 srv_use_stored_prim ();
1355
1356 EM_CC_CALL_HOLD_REJECT;
1357
1358 CCD_END;
1359 }
1360 else
1361 {
1362 CCD_END;
1363 /* Implements Measure# 3 and streamline encoding */
1364 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1365 }
1366 break;
1367
1368 default:
1369 CCD_END;
1370 /* Implements Measure# 3 and streamline encoding */
1371 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1372 break;
1373 }
1374 }
1375
1376 /*
1377 +--------------------------------------------------------------------+
1378 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
1379 | STATE : code ROUTINE : cc_retrieve_ack |
1380 +--------------------------------------------------------------------+
1381
1382 PURPOSE : Processing an incoming retrieve ack message.
1383
1384 */
1385
1386 GLOBAL void cc_retrieve_ack (void)
1387 {
1388 GET_INSTANCE_DATA;
1389
1390 TRACE_FUNCTION ("cc_retrieve_ack()");
1391
1392 switch (cc_data->state[cc_data->index_ti])
1393 {
1394 /*
1395 * CS_0 is handled by the formatter
1396 */
1397 case M_CC_CS_10:
1398 if (cc_check_error_flag ())
1399 {
1400 CCD_END;
1401 if (cc_data->hold_state[cc_data->index_ti] EQ M_CC_HLD_RETRIEVE_REQ)
1402 {
1403 PALLOC (retrieve_cnf, MNCC_RETRIEVE_CNF);
1404
1405 cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_IDLE;
1406 retrieve_cnf->ti = cc_data->ti;
1407 retrieve_cnf->cause = MNCC_CAUSE_RETRIEVE_SUCCESS;
1408 PSENDX (MMI, retrieve_cnf);
1409
1410 EM_CC_CALL_RETRIEVE_ACKNOWLEDGE;
1411
1412 }
1413 else
1414 {
1415 /* Implements Measure# 3 and streamline encoding */
1416 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1417 }
1418 }
1419 break;
1420
1421 default:
1422 CCD_END;
1423 /* Implements Measure# 3 and streamline encoding */
1424 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1425 break;
1426 }
1427 }
1428
1429 /*
1430 +--------------------------------------------------------------------+
1431 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
1432 | STATE : code ROUTINE : cc_retrieve_rej |
1433 +--------------------------------------------------------------------+
1434
1435 PURPOSE : Processing an incoming retrieve rej message.
1436
1437 */
1438
1439 GLOBAL void cc_retrieve_rej (T_D_RETRIEVE_REJ * retrieve_rej)
1440 {
1441 GET_INSTANCE_DATA;
1442 TRACE_FUNCTION ("cc_retrieve_rej()");
1443
1444 switch (cc_data->state[cc_data->index_ti])
1445 {
1446 /*
1447 * CS_0 is handled by the formatter
1448 */
1449 case M_CC_CS_10:
1450 if (cc_data->hold_state[cc_data->index_ti] EQ M_CC_HLD_RETRIEVE_REQ)
1451 {
1452 PALLOC (retrieve_cnf, MNCC_RETRIEVE_CNF);
1453
1454 cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_CALL_HELD;
1455 retrieve_cnf->ti = cc_data->ti;
1456
1457 /*
1458 * It is possible for the network to send a REJ without a Cause IE.
1459 * This causes the decoder to flag a Madatory IE error. According to
1460 * 04.08 Sec: 8.5.3.e, the REJ should still be managed as if a correctly
1461 * formatted REJ had been received.
1462 */
1463 if (!retrieve_rej->cc_cause.v_cause)
1464 {
1465 retrieve_cnf->cause = MNCC_CAUSE_NO_NET_CAUSE;
1466 }
1467 else
1468 {
1469 retrieve_cnf->cause = CAUSE_MAKE(DEFBY_STD,
1470 ORIGSIDE_NET,
1471 MNCC_CC_ORIGINATING_ENTITY,
1472 retrieve_rej->cc_cause.cause);
1473 }
1474 PSENDX (MMI, retrieve_cnf);
1475 srv_use_stored_prim ();
1476
1477 EM_CC_CALL_RETRIEVE_REJECT;
1478
1479 CCD_END;
1480 }
1481 else
1482 {
1483 CCD_END;
1484 /* Implements Measure# 3 and streamline encoding */
1485 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1486 }
1487 break;
1488
1489 default:
1490 CCD_END;
1491 /* Implements Measure# 3 and streamline encoding */
1492 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1493 break;
1494 }
1495 }
1496
1497 /*
1498 +--------------------------------------------------------------------+
1499 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
1500 | STATE : code ROUTINE : cc_congestion_control |
1501 +--------------------------------------------------------------------+
1502
1503 PURPOSE : Processing an incoming congestion control message.
1504
1505 */
1506
1507 GLOBAL void cc_congestion_control (T_B_CONGEST_CTRL * cong)
1508 {
1509 GET_INSTANCE_DATA;
1510 TRACE_FUNCTION ("cc_congestion_control()");
1511
1512 switch (cc_data->state[cc_data->index_ti])
1513 {
1514 /*
1515 * CS_0 is handled by the formatter
1516 */
1517 case M_CC_CS_10:
1518 if (cc_check_error_flag ())
1519 {
1520 PALLOC (user, MNCC_USER_IND);
1521
1522 cc_build_user_ind_from_cong (user, cong);
1523 PSENDX (MMI, user);
1524 CCD_END;
1525 }
1526 break;
1527
1528 default:
1529 CCD_END;
1530 /* Implements Measure# 3 and streamline encoding*/
1531 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1532 break;
1533 }
1534 }
1535
1536 /*
1537 +--------------------------------------------------------------------+
1538 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
1539 | STATE : code ROUTINE : cc_user_information |
1540 +--------------------------------------------------------------------+
1541
1542 PURPOSE : Processing an incoming user information message.
1543
1544 */
1545
1546 GLOBAL void cc_user_information ( T_B_USER_INFO * user)
1547 {
1548 GET_INSTANCE_DATA;
1549 TRACE_FUNCTION ("cc_user_information()");
1550
1551 switch (cc_data->state[cc_data->index_ti])
1552 {
1553 /*
1554 * CS_0 is handled by the formatter
1555 */
1556 case M_CC_CS_10:
1557 if (cc_check_error_flag ())
1558 {
1559 PALLOC (user_ind, MNCC_USER_IND);
1560
1561 cc_build_user_ind_from_user (user_ind, user);
1562 CCD_END;
1563 PSENDX (MMI, user_ind);
1564
1565 EM_CC_USER_TO_USER_DATA_RECEIVED;
1566
1567 }
1568 break;
1569
1570 default:
1571 CCD_END;
1572 /* Implements Measure# 4 and streamline encoding*/
1573 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1574 break;
1575 }
1576 }
1577
1578 /*
1579 +--------------------------------------------------------------------+
1580 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
1581 | STATE : code ROUTINE : cc_modify |
1582 +--------------------------------------------------------------------+
1583
1584 PURPOSE : Processing an incoming modify message.
1585
1586 */
1587
1588 GLOBAL void cc_modify (T_B_MODIFY * modify)
1589 {
1590 GET_INSTANCE_DATA;
1591
1592 TRACE_FUNCTION ("cc_modify()");
1593
1594 switch (cc_data->state[cc_data->index_ti])
1595 {
1596 /*
1597 * CS_0 is handled by the formatter
1598 */
1599 case M_CC_CS_10:
1600 if (cc_check_error_flag ())
1601 {
1602 switch (cc_data->neg_ri)
1603 {
1604 case M_CC_REPEAT_CIRCULAR:
1605 if (cc_data->active_service EQ cc_data->neg_serv1)
1606 {
1607 if (cc_bcs_compatible (&modify->bearer_cap,
1608 &cc_data->neg_bc2, TRUE) EQ TRUE)
1609 {
1610 CCD_END;
1611 cc_mod_complete ();
1612 }
1613 else
1614 {
1615 CCD_END;
1616 cc_mod_reject ();
1617 }
1618 }
1619 else
1620 {
1621 if (cc_bcs_compatible (&modify->bearer_cap,
1622 &cc_data->neg_bc1, TRUE) EQ TRUE)
1623 {
1624 CCD_END;
1625 cc_mod_complete ();
1626 }
1627 else
1628 {
1629 CCD_END;
1630 cc_mod_reject ();
1631 }
1632 }
1633 break;
1634 #ifndef REL99
1635 case M_CC_REPEAT_SEQUENTIAL:
1636 if (cc_data->active_service EQ cc_data->neg_serv1)
1637 {
1638 if (cc_bcs_compatible (&modify->bearer_cap,
1639 &cc_data->neg_bc2, TRUE) EQ TRUE)
1640 {
1641 CCD_END;
1642 cc_mod_complete ();
1643 }
1644 else
1645 {
1646 CCD_END;
1647 cc_mod_reject ();
1648 }
1649 }
1650 else
1651 {
1652 CCD_END;
1653 cc_mod_reject ();
1654 }
1655 break;
1656 #endif /* #ifndef REL99 */
1657 default:
1658 CCD_END;
1659 cc_mod_reject ();
1660 break;
1661 }
1662 }
1663 break;
1664
1665 default:
1666 CCD_END;
1667 /* Implements Measure# 5 and streamline encoding*/
1668 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1669 break;
1670 }
1671 }
1672
1673 /*
1674 +--------------------------------------------------------------------+
1675 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
1676 | STATE : code ROUTINE : cc_mod_reject |
1677 +--------------------------------------------------------------------+
1678
1679 PURPOSE : Negative end of a mobile terminated in-call modification.
1680
1681 */
1682
1683 GLOBAL void cc_mod_reject (void)
1684 {
1685 GET_INSTANCE_DATA;
1686 TRACE_FUNCTION ("cc_mod_reject()");
1687
1688 CCD_START;
1689 {
1690 MCAST (modify_rej, B_MODIFY_REJ);
1691
1692
1693 cc_build_modify_reject (modify_rej,
1694 CAUSE_MAKE(DEFBY_STD,
1695 ORIGSIDE_MS,
1696 MNCC_CC_ORIGINATING_ENTITY,
1697 M_CC_CAUSE_BEARER_CAP_AUTHORIZ));
1698 for_modify_reject (modify_rej);
1699 }
1700
1701 EM_CC_MT_IN_CALL_MODIFICATION_FAILED;
1702
1703 CCD_END;
1704 }
1705
1706 /*
1707 +--------------------------------------------------------------------+
1708 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
1709 | STATE : code ROUTINE : cc_mod_complete |
1710 +--------------------------------------------------------------------+
1711
1712 PURPOSE : Positive end of a mobile terminated in-call modification.
1713
1714 */
1715
1716 GLOBAL void cc_mod_complete (void)
1717 {
1718 GET_INSTANCE_DATA;
1719 TRACE_FUNCTION ("cc_mod_complete()");
1720
1721 CCD_START;
1722 {
1723 MCAST (modify_com, B_MODIFY_COMP);
1724 PALLOC (mod_ind, MNCC_MODIFY_IND);
1725
1726
1727 if (cc_data->active_service EQ cc_data->neg_serv1)
1728 cc_data->active_service = cc_data->neg_serv2;
1729 else
1730 cc_data->active_service = cc_data->neg_serv1;
1731
1732 mod_ind->ti = cc_data->ti;
1733 mod_ind->serv = cc_data->active_service;
1734 PSENDX (MMI, mod_ind);
1735
1736 EM_CC_MT_IN_CALL_MODIFICATION_PASSED;
1737
1738 cc_build_modify_complete (modify_com);
1739 for_modify_complete (modify_com);
1740 }
1741 CCD_END;
1742 }
1743
1744 /*
1745 +--------------------------------------------------------------------+
1746 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
1747 | STATE : code ROUTINE : cc_modify_complete |
1748 +--------------------------------------------------------------------+
1749
1750 PURPOSE : Processing an incoming modify complete message.
1751
1752 */
1753
1754 GLOBAL void cc_modify_complete ( T_B_MODIFY_COMP * mod_com)
1755 {
1756 GET_INSTANCE_DATA;
1757 TRACE_FUNCTION ("cc_modify_complete()");
1758
1759 switch (cc_data->state[cc_data->index_ti])
1760 {
1761 /*
1762 * CS_0 is handled by the formatter
1763 */
1764 case M_CC_CS_26:
1765 if (cc_check_error_flag ())
1766 {
1767 if (cc_data->new_itc EQ mod_com->bearer_cap.trans_cap)
1768 {
1769 PALLOC (mod_cnf, MNCC_MODIFY_CNF);
1770
1771 TIMERSTOP (TIMER_CC);
1772 if (cc_data->active_service EQ cc_data->serv1)
1773 cc_data->active_service = cc_data->serv2;
1774 else
1775 cc_data->active_service = cc_data->serv1;
1776 mod_cnf->ti = cc_data->ti;
1777 mod_cnf->cause = MNCC_CAUSE_MODIFY_SUCCESS;
1778 /* Setting raw_cause to empty as we are not sending any cause from network*/
1779 mod_cnf->c_raw_cause = 0;
1780
1781 EM_CC_MO_IN_CALL_MODIFICATION_PASSED;
1782
1783 PSENDX (MMI, mod_cnf);
1784 cc_set_state (M_CC_CS_10);
1785 }
1786 CCD_END;
1787 }
1788 break;
1789
1790 default:
1791 CCD_END;
1792 /* Implements Measure# 6 and streamline encoding*/
1793 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1794 break;
1795 }
1796 }
1797
1798 /*
1799 +--------------------------------------------------------------------+
1800 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
1801 | STATE : code ROUTINE : cc_modify_reject |
1802 +--------------------------------------------------------------------+
1803
1804 PURPOSE : Processing an incoming modify reject message.
1805
1806 */
1807
1808 GLOBAL void cc_modify_reject (T_B_MODIFY_REJ * mod_rej)
1809 {
1810 GET_INSTANCE_DATA;
1811 TRACE_FUNCTION ("cc_modify_reject()");
1812
1813 switch (cc_data->state[cc_data->index_ti])
1814 {
1815 /*
1816 * CS_0 is handled by the formatter
1817 */
1818 case M_CC_CS_26:
1819 if (cc_check_error_flag ())
1820 {
1821 if (cc_data->old_itc EQ mod_rej->bearer_cap.trans_cap)
1822 {
1823 PALLOC (mod_cnf, MNCC_MODIFY_CNF);
1824
1825 TIMERSTOP (TIMER_CC);
1826 mod_cnf->ti = cc_data->ti;
1827 /*
1828 * cause IE is mandatory and the check for presence has been done
1829 * already thus there is no need to check for validity of cause IE
1830 * here anymore
1831 */
1832 mod_cnf->cause = CAUSE_MAKE(DEFBY_STD,
1833 ORIGSIDE_NET,
1834 MNCC_CC_ORIGINATING_ENTITY,
1835 mod_rej->cc_cause.cause);
1836 mod_cnf->c_raw_cause = cc_build_cause (&mod_rej->cc_cause,
1837 mod_cnf->raw_cause);
1838 PSENDX (MMI, mod_cnf);
1839 cc_set_state (M_CC_CS_10);
1840 }
1841
1842 EM_CC_MO_IN_CALL_MODIFICATION_FAILED;
1843
1844 CCD_END;
1845 }
1846 break;
1847
1848 default:
1849 CCD_END;
1850 /* Implements Measure# 7 and streamline encoding*/
1851 cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
1852 break;
1853 }
1854 }
1855
1856
1857 /*
1858 +--------------------------------------------------------------------+
1859 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
1860 | STATE : code ROUTINE : cc_status |
1861 +--------------------------------------------------------------------+
1862
1863 PURPOSE : Processing an incoming status message.
1864
1865 */
1866
1867 GLOBAL void cc_status (T_B_STATUS * status)
1868 {
1869 GET_INSTANCE_DATA;
1870 TRACE_FUNCTION ("cc_status()");
1871
1872 /* The cause is in STATUS a mandatory IE (given intact message) */
1873 TRACE_EVENT_P1 ("STATUS cause: %02x", status->cc_cause.cause);
1874
1875 switch (cc_data->state[cc_data->index_ti])
1876 {
1877 case M_CC_CS_0:
1878 CCD_END;
1879 if (status->call_state.state NEQ M_CC_CS_0)
1880 {
1881 CCD_START;
1882 {
1883 MCAST (rel_com, U_RELEASE_COMP);
1884
1885 cc_build_release_complete (rel_com,
1886 CAUSE_MAKE(DEFBY_STD,
1887 ORIGSIDE_MS,
1888 MNCC_CC_ORIGINATING_ENTITY,
1889 M_CC_CAUSE_MESSAGE_INCOMPAT));
1890 for_release_complete (rel_com);
1891 }
1892 CCD_END;
1893 }
1894 for_rel_req ();
1895 break;
1896
1897 case M_CC_CS_1:
1898 case M_CC_CS_3:
1899 case M_CC_CS_4:
1900 case M_CC_CS_6:
1901 case M_CC_CS_7:
1902 case M_CC_CS_8:
1903 case M_CC_CS_9:
1904 case M_CC_CS_10:
1905 case M_CC_CS_26:
1906 if (cc_check_error_flag ())
1907 {
1908 /* check for incompatible state */
1909 if (status->call_state.state NEQ cc_data->state[cc_data->index_ti])
1910 {
1911 PALLOC (rel_ind, MNCC_RELEASE_IND);
1912
1913 cc_reset_dtmf (); // China change HM 11.07.00
1914
1915 TIMERSTOP (TIMER_CC);
1916
1917 rel_ind->ti = cc_data->ti;
1918
1919 rel_ind->cause = CAUSE_MAKE(DEFBY_STD,
1920 ORIGSIDE_MS,
1921 MNCC_CC_ORIGINATING_ENTITY,
1922 M_CC_CAUSE_MESSAGE_INCOMPAT);
1923 rel_ind->c_raw_cause = 0;
1924 PSENDX (MMI, rel_ind);
1925
1926 CCD_END;
1927 CCD_START;
1928 {
1929 MCAST (rel_com, U_RELEASE_COMP);
1930
1931 cc_build_release_complete (rel_com,
1932 CAUSE_MAKE(DEFBY_STD,
1933 ORIGSIDE_MS,
1934 MNCC_CC_ORIGINATING_ENTITY,
1935 M_CC_CAUSE_MESSAGE_INCOMPAT));
1936 for_release_complete (rel_com);
1937 }
1938 CCD_END;
1939 for_rel_req ();
1940 cc_set_state (M_CC_CS_0);
1941 }
1942 else
1943 /*
1944 * compatible, perform checks/ actions of 04.08, ch. 5.5.3.2.2;
1945 * Condat action (option!) is to initiate normal call clearing
1946 * (with DISCONNECT)
1947 */
1948 {
1949 if ((status->cc_cause.cause >= M_CC_CAUSE_INCORRECT_MESSAGE)
1950 AND
1951 (status->cc_cause.cause <= M_CC_CAUSE_COND_INFO_ELEM))
1952 {
1953 /*
1954 * Block entered for
1955 * CAUSE_INCORRECT_MESSAGE, CAUSE_INVALID_MAND_INFO,
1956 * CAUSE_MESSAGE_TYPE_NOT_IMPLEM, CAUSE_MESSAGE_TYPE_INCOMPAT,
1957 * CAUSE_INFO_ELEM_NOT_IMPLEM, CAUSE_COND_INFO_ELEM. (0x5f..0x64)
1958 */
1959 if ((cc_data->state[cc_data->index_ti] EQ M_CC_CS_10) AND
1960 (cc_data->hold_state[cc_data->index_ti] EQ M_CC_HLD_HOLD_REQ))
1961 {
1962 /*
1963 * Compatible state, last CC message was a hold request which is
1964 * not supported by the network. Handled like HOLD REJECT.
1965 */
1966 PALLOC (hold_cnf, MNCC_HOLD_CNF); /* T_MNCC_HOLD_CNF */
1967 cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_IDLE;
1968 hold_cnf->ti = cc_data->ti;
1969 hold_cnf->cause = CAUSE_MAKE(DEFBY_STD,
1970 ORIGSIDE_NET,
1971 MNCC_CC_ORIGINATING_ENTITY,
1972 status->cc_cause.cause);
1973 PSENDX (MMI, hold_cnf);
1974 CCD_END;
1975 srv_use_stored_prim ();
1976 }
1977 else if (status->cc_cause.cause NEQ M_CC_CAUSE_INFO_ELEM_NOT_IMPLEM)
1978 {
1979 /*
1980 * Compatible state, special condition for HOLD REQUEST not met.
1981 * The network is also not complaining about an optional
1982 * information element which can be simply ignored.
1983 * Disconnect the call.
1984 */
1985 PALLOC (disc_ind, MNCC_DISCONNECT_IND);
1986
1987 TIMERSTOP (TIMER_CC);
1988
1989 disc_ind->ti = cc_data->ti;
1990 disc_ind->cause = CAUSE_MAKE(DEFBY_STD,
1991 ORIGSIDE_NET,
1992 MNCC_CC_ORIGINATING_ENTITY,
1993 status->cc_cause.cause);
1994 disc_ind->c_raw_cause = cc_build_cause (&status->cc_cause,
1995 disc_ind->raw_cause);
1996 disc_ind->diagnostic = NOT_PRESENT_8BIT;
1997 disc_ind->progress_desc = MNCC_PROG_NOT_PRES;
1998 PSENDX (MMI, disc_ind);
1999
2000 CCD_END;
2001 CCD_START;
2002 {
2003 MCAST (disconnect, U_DISCONNECT);
2004
2005 cc_build_disconnect (disconnect,
2006 CAUSE_MAKE(DEFBY_STD,
2007 ORIGSIDE_MS,
2008 MNCC_CC_ORIGINATING_ENTITY,
2009 M_CC_CAUSE_CALL_CLEAR),
2010 NULL, MNCC_SS_VER_NOT_PRES);
2011 for_disconnect (disconnect);
2012 }
2013 TIMERSTART (T305, T305_VALUE);
2014 cc_set_state (M_CC_CS_11);
2015 }
2016 }
2017 else
2018 {
2019 /*
2020 * STATUS message but neither incompatible state nor indicating
2021 * incorrect message / IE; check if we received a STATUS with cause
2022 * "message not compatible with protocol state". GSM 04.08 does not
2023 * define what to do and also does not define that this case has to
2024 * be handled at all;
2025 * Condat (HM) decided to "clear DTMF" if it was running to try to
2026 * recover from the misaligned states scenario.
2027 */
2028 T_DTMF *p_dtmf;
2029
2030 p_dtmf = &cc_data->dtmf[cc_data->index_ti];
2031 if ((p_dtmf->state EQ DTMF_SEND_REQUEST) AND
2032 (status->cc_cause.cause EQ M_CC_CAUSE_MESSAGE_INCOMPAT))
2033 {
2034 /* Send negative acknowledge for DTMF send request to MMI */
2035 PALLOC (mncc_start_dtmf_cnf, MNCC_START_DTMF_CNF);
2036 mncc_start_dtmf_cnf->ti = cc_data->ti;
2037 mncc_start_dtmf_cnf->key = NOT_PRESENT_8BIT;
2038 mncc_start_dtmf_cnf->dtmf_mod = NOT_PRESENT_8BIT;
2039 mncc_start_dtmf_cnf->cause = CAUSE_MAKE(DEFBY_STD,
2040 ORIGSIDE_NET,
2041 MNCC_CC_ORIGINATING_ENTITY,
2042 M_CC_CAUSE_MESSAGE_INCOMPAT);
2043 PSENDX (MMI, mncc_start_dtmf_cnf);
2044 }
2045
2046 /* Bring screwed up network back to work */
2047 for_stop_dtmf ();
2048
2049 /* Reset screwed up DTMF state machine */
2050 p_dtmf->state = DTMF_IDLE;
2051 p_dtmf->read = 0;
2052 p_dtmf->write = 0;
2053 }
2054 CCD_END;
2055 }
2056 }
2057 break;
2058
2059 case M_CC_CS_11:
2060 case M_CC_CS_12:
2061 if (cc_check_error_flag ())
2062 {
2063 if (status->call_state.state NEQ cc_data->state[cc_data->index_ti])
2064 {
2065 /*
2066 * STATUS message with incompatible state
2067 * On receipt of a STATUS message reporting an incompatible call
2068 * control state, the receiving entity shall clear the call by
2069 * sending a RELEASE COMPLETE message with cause # 101 "message
2070 * not compatible with protocol state". The reported call control
2071 * state is incompatible if the combination of call control states
2072 * at the sender and receiver side cannot occur, do not match or cannot
2073 * be aligned by actions of the receiver; the exact definition is
2074 * implementation dependent. [04.08 clause 5.5.3.2.1]
2075 */
2076 cc_reset_dtmf ();
2077
2078 TIMERSTOP (TIMER_CC);
2079
2080 /* Send MNCC_RELEASE_IND to MMI */
2081 {
2082 PALLOC (rel_ind, MNCC_RELEASE_IND); /* T_MNCC_RELEASE_IND */
2083 rel_ind->ti = cc_data->ti;
2084 rel_ind->cause = CAUSE_MAKE(DEFBY_STD,
2085 ORIGSIDE_MS,
2086 MNCC_CC_ORIGINATING_ENTITY,
2087 M_CC_CAUSE_MESSAGE_INCOMPAT);
2088 rel_ind->c_raw_cause = 0;
2089 PSENDX (MMI, rel_ind);
2090 }
2091
2092 CCD_END;
2093 CCD_START;
2094 {
2095 MCAST (rel_com, U_RELEASE_COMP); /* T_U_RELEASE_COMP */
2096 cc_build_release_complete (rel_com,
2097 CAUSE_MAKE(DEFBY_STD,
2098 ORIGSIDE_MS,
2099 MNCC_CC_ORIGINATING_ENTITY,
2100 M_CC_CAUSE_MESSAGE_INCOMPAT));
2101 for_release_complete (rel_com);
2102 for_rel_req ();
2103 cc_set_state (M_CC_CS_0);
2104 }
2105 }
2106 CCD_END;
2107 }
2108 break;
2109
2110 case M_CC_CS_19:
2111 if (cc_check_error_flag ())
2112 {
2113 if (status->call_state.state NEQ cc_data->state[cc_data->index_ti])
2114 {
2115 TIMERSTOP (TIMER_CC);
2116
2117 cc_reset_dtmf ();
2118
2119 {
2120 PALLOC (rel_cnf, MNCC_RELEASE_CNF); /* T_MNCC_RELEASE_CNF */
2121 rel_cnf->ti = cc_data->ti;
2122 rel_cnf->cause = CAUSE_MAKE(DEFBY_STD,
2123 ORIGSIDE_MS,
2124 MNCC_CC_ORIGINATING_ENTITY,
2125 M_CC_CAUSE_MESSAGE_INCOMPAT);
2126 /* Setting raw_cause to empty as this is a local release
2127 * of MM connection,CC is not receiving any cause value
2128 * from Network
2129 */
2130 rel_cnf->c_raw_cause = 0;
2131 PSENDX (MMI, rel_cnf);
2132 }
2133
2134 CCD_END;
2135 CCD_START;
2136 {
2137 MCAST (rel_com, U_RELEASE_COMP); /* T_U_RELEASE_COMP */
2138 cc_build_release_complete (rel_com,
2139 CAUSE_MAKE(DEFBY_STD,
2140 ORIGSIDE_MS,
2141 MNCC_CC_ORIGINATING_ENTITY,
2142 M_CC_CAUSE_MESSAGE_INCOMPAT));
2143 for_release_complete (rel_com);
2144 for_rel_req ();
2145 cc_set_state (M_CC_CS_0);
2146 }
2147 }
2148 CCD_END;
2149 }
2150 break;
2151
2152 default:
2153 CCD_END;
2154 break;
2155 }
2156
2157 EM_CC_STATUS_RECEIVED;
2158
2159 }
2160
2161 /*
2162 +--------------------------------------------------------------------+
2163 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
2164 | STATE : code ROUTINE : cc_status_enquiry |
2165 +--------------------------------------------------------------------+
2166
2167 PURPOSE : Processing an incoming status enquiry message.
2168
2169 */
2170
2171 GLOBAL void cc_status_enquiry (void)
2172 {
2173 GET_INSTANCE_DATA;
2174
2175 TRACE_FUNCTION ("cc_status_enquiry()");
2176
2177 /*
2178 * CS_0 is handled by the formatter
2179 */
2180 switch (cc_data->state[cc_data->index_ti])
2181 {
2182 case M_CC_CS_10:
2183 /*
2184 * Ensure synchronization of auxiliary states with ACI.
2185 */
2186 if (cc_check_error_flag ())
2187 {
2188 CCD_END;
2189 {
2190 PALLOC (mncc_status_ind, MNCC_STATUS_IND);
2191 mncc_status_ind->ti = cc_data->ti;
2192 PSENDX (MMI, mncc_status_ind);
2193 }
2194
2195 EM_CC_STATUS_ENQUIRY_RECEIVED;
2196
2197 }
2198 break;
2199
2200 default:
2201 /*
2202 * No auxiliary states in non-active states. Immediate response is safe.
2203 */
2204 if (cc_check_error_flag ())
2205 {
2206 CCD_END;
2207 /* EM call moved above cc_send_status should not have any impact */
2208 EM_CC_STATUS_ENQUIRY_RECEIVED;
2209
2210 /* Implements Measure# 7 and streamline encoding*/
2211 cc_send_status (M_CC_CAUSE_STATUS_ENQUIRY);
2212 }
2213 break;
2214 }
2215 }
2216
2217
2218 /*
2219 +--------------------------------------------------------------------+
2220 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
2221 | STATE : code ROUTINE : cc_unknown_message |
2222 +--------------------------------------------------------------------+
2223
2224 PURPOSE : Processing of an incoming unknown message.
2225
2226 */
2227
2228 GLOBAL void cc_unknown_message (void)
2229 {
2230
2231 CCD_END;
2232 CCD_START;
2233 {
2234 MCAST (status, B_STATUS);
2235
2236 TRACE_FUNCTION ("cc_unknown_message()");
2237
2238 cc_build_status (status,
2239 CAUSE_MAKE(DEFBY_STD,
2240 ORIGSIDE_MS,
2241 MNCC_CC_ORIGINATING_ENTITY,
2242 M_CC_CAUSE_MESSAGE_TYPE_NOT_IMPLEM));
2243 for_status (status);
2244 }
2245 CCD_END;
2246 }
2247
2248 /* Implements Measure# 18 */
2249 /*
2250 +--------------------------------------------------------------------+
2251 | PROJECT : GSM-PS (6147) MODULE : CC_ACT |
2252 | STATE : code ROUTINE : cc_mncc_hold_retrieve_req |
2253 +--------------------------------------------------------------------+
2254
2255 PURPOSE : Send hold REQ/retrieve REQ.
2256
2257 */
2258
2259 LOCAL void cc_mncc_hold_retrieve_req (T_PRIM * prim)
2260 {
2261 GET_INSTANCE_DATA;
2262 UBYTE ti;
2263
2264 TRACE_FUNCTION ("cc_mncc_hold_retrieve_req()");
2265
2266 if(prim->custom.opc EQ MNCC_HOLD_REQ)
2267 {
2268 ti = ((T_MNCC_HOLD_REQ *)P2D(prim))->ti;
2269 }
2270 else
2271 {
2272 ti = ((T_MNCC_RETRIEVE_REQ *)P2D(prim))->ti;
2273 }
2274 if ((cc_data->index_ti = srv_convert_ti (ti)) EQ NOT_PRESENT_8BIT)
2275 {
2276 PFREE (P2D(prim));
2277 return;
2278 }
2279
2280 switch (cc_data->state[cc_data->index_ti])
2281 {
2282 case M_CC_CS_10:
2283 if(prim->custom.opc EQ MNCC_HOLD_REQ)
2284 {
2285 /* We should think about storing the hold request
2286 until DTMF idle state reached. ...
2287 This causes some other changes, we have to add some
2288 calls to serv_use_stored_prim() at some places after
2289 state transition of the DTMF state machine to DTMF idle.*/
2290 cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_HOLD_REQ;
2291 for_hold ();
2292 EM_CC_CALL_HOLD;
2293 }
2294 else
2295 {
2296 cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_RETRIEVE_REQ;
2297 for_retrieve ();
2298 EM_CC_CALL_RETRIEVE;
2299 }
2300 PFREE (P2D(prim));
2301
2302 break;
2303
2304 case CS_101:
2305 case M_CC_CS_26:
2306 case CS_261:
2307 srv_store_prim (prim);
2308 break;
2309
2310 default:
2311 PFREE (P2D(prim));
2312 break;
2313 }
2314 }
2315
2316 #endif