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