FreeCalypso > hg > tcs211-l1-reconst
diff g23m/condat/ms/src/aci/cmh_ccs.c @ 0:509db1a7b7b8
initial import: leo2moko-r1
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 01 Jun 2015 03:24:05 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/g23m/condat/ms/src/aci/cmh_ccs.c Mon Jun 01 03:24:05 2015 +0000 @@ -0,0 +1,4940 @@ +/* ++----------------------------------------------------------------------------- +| Project : GSM-PS (6147) +| Modul : CMH_CCS ++----------------------------------------------------------------------------- +| Copyright 2002 Texas Instruments Berlin, AG +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Berlin, AG +| The receipt of or possession of this file does not convey +| any rights to reproduce or disclose its contents or to +| manufacture, use, or sell anything it may describe, in +| whole, or in part, without the specific written consent of +| Texas Instruments Berlin, AG. ++----------------------------------------------------------------------------- +| Purpose : This module provides the set functions related to the +| protocol stack adapter for call control. ++----------------------------------------------------------------------------- +*/ + +#ifndef CMH_CCS_C +#define CMH_CCS_C +#endif + +#include "aci_all.h" + +#include "aci_cmh.h" +#include "ksd.h" + +/*==== INCLUDES ===================================================*/ + +/* for CCD */ +#include "ccdapi.h" +#include "aci.h" /* for CCD_END... */ + +/***********/ + +#include "ati_cmd.h" +#include "aci_cmd.h" + +#ifdef DTI +#include "dti.h" /* functionality of the dti library */ +#include "dti_conn_mng.h" +#include "dti_cntrl_mng.h" +#endif + +#ifdef FAX_AND_DATA +#include "aci_fd.h" +#endif /* of #ifdef FAX_AND_DATA */ + +#ifdef FF_TTY +#include "audio.h" +#endif + +#include "aci_mem.h" +#include "l4_tim.h" + +#include "phb.h" +#include "psa.h" +#include "psa_cc.h" +#include "psa_sim.h" +#include "psa_mm.h" +#include "psa_ss.h" +#include "psa_util.h" +#include "cmh.h" +#include "cmh_cc.h" +#include "cmh_mm.h" +#include "cmh_sim.h" +#include "cmh_phb.h" + +#ifdef FF_ATI +#include "aci_io.h" +#endif /* of #ifdef FF_ATI */ + +#ifdef FAX_AND_DATA + +#include "psa_ra.h" +#include "cmh_ra.h" +#include "psa_l2r.h" +#include "cmh_l2r.h" +#include "psa_tra.h" + +#ifdef FF_FAX +#include "psa_t30.h" +#include "cmh_t30.h" +#endif /* FF_FAX */ + +#endif /* FAX_AND_DATA */ + +#ifdef SIM_TOOLKIT +#include "psa_sat.h" +#include "cmh_sat.h" +#endif + +#ifdef DTI +#if defined (FF_WAP) || defined (FF_GPF_TCPIP) || defined (FF_SAT_E) +#include "wap_aci.h" +#include "psa_ppp_w.h" +#include "cmh_ppp.h" +#endif /* FF_WAP || FF_GPF_TCPIP || FF_SAT_E */ +#endif /* DTI */ + +#ifdef GPRS +#include "gaci.h" +#include "gaci_cmh.h" +#include "psa_sm.h" +#include "cmh_sm.h" +#endif /* GPRS */ + +#include "aoc.h" +#include "ksd.h" + +#ifdef ACI +#include "cmh_mmi.h" +#endif + +#ifdef FF_PSI +#include "psa_psi.h" +#include "cmh_psi.h" +#include "cmh_uart.h" +#include "ati_src_psi.h" +#endif /* FF_PSI */ + +/*==== CONSTANTS ==================================================*/ +GLOBAL T_ACI_CC_REDIAL_BLACKL * cc_blacklist_ptr = NULL; +/*==== EXPORT =====================================================*/ + + +#if defined (GPRS) AND defined (DTI) +EXTERN T_ATI_RSLT atGD (char *cl, UBYTE srcId, BOOL *gprs_command); +#endif /* GPRS */ + +/*==== VARIABLES ==================================================*/ + +EXTERN T_PCEER causeMod; +EXTERN SHORT causeCeer; +/* parameter block for delayed cmhCC_Dial call */ +LOCAL struct cmhCC_Dial_buffer { + T_ACI_CMD_SRC srcId; +} cmhCC_Dial_buffer; + +EXTERN T_ACI_CUSCFG_PARAMS cuscfgParams; + +/*==== PROTOTYPES =================================================*/ + +LOCAL UCHAR cmhCC_Dial_delayed (void *arg); +LOCAL T_ACI_RETURN chld_RelHldOrUdub(T_ACI_CMD_SRC srcId); +LOCAL T_ACI_RETURN chld_RelActAndAcpt(T_ACI_CMD_SRC srcId); +LOCAL T_ACI_RETURN chld_RelActSpec(T_ACI_CMD_SRC srcId, CHAR *call); +LOCAL T_ACI_RETURN chld_HldActAndAcpt(T_ACI_CMD_SRC srcId); +LOCAL T_ACI_RETURN chld_HldActExc(T_ACI_CMD_SRC srcId, CHAR *call); +LOCAL T_ACI_RETURN chld_AddHld(T_ACI_CMD_SRC srcId); +LOCAL T_ACI_RETURN chld_Ect(T_ACI_CMD_SRC srcId); +LOCAL T_ACI_RETURN chld_Ccbs(T_ACI_CMD_SRC srcId); +LOCAL T_ACI_RETURN chld_OnlyHold(T_ACI_CMD_SRC srcId); +LOCAL T_ACI_RETURN chld_RelDialCall(T_ACI_CMD_SRC srcId); +LOCAL T_ACI_RETURN chld_RetrieveHoldCall(T_ACI_CMD_SRC srcId); +LOCAL T_ACI_RETURN chld_RetrieveHoldCallSpec(T_ACI_CMD_SRC srcId, CHAR *call); +LOCAL T_ACI_RETURN chld_RelAnySpec(T_ACI_CMD_SRC srcId, CHAR *call); + +/*==== FUNCTIONS ==================================================*/ + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_Dm | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the D> AT command + which is responsible to originate a call using the phone- + book. The searched number can be declared either by the + name or by giving the index of a specified phonebook. If + an entry could be found, the ordinary AT D command is + called. + + <str> : name string to search. + <mem> : type of phonebook. + <index> : phonebook index. + <clirOvrd>: CLIR override + <cugCtrl> : CUG control + <callType>: call type +*/ + +#define RETURN(x) { retVal = x; goto cleanup_exit; } +/*lint -e{801} Use of goto*/ +#ifdef NO_ASCIIZ +GLOBAL T_ACI_RETURN sAT_Dm ( T_ACI_CMD_SRC srcId, + T_ACI_PB_TEXT *str, + T_ACI_PB_STOR mem, + SHORT index, + T_ACI_D_CLIR_OVRD clirOvrd, + T_ACI_D_CUG_CTRL cugCtrl, + T_ACI_D_TOC callType ) +#else /* ifdef NO_ASCIIZ */ +GLOBAL T_ACI_RETURN sAT_Dm ( T_ACI_CMD_SRC srcId, + CHAR *str, + T_ACI_PB_STOR mem, + SHORT index, + T_ACI_D_CLIR_OVRD clirOvrd, + T_ACI_D_CUG_CTRL cugCtrl, + T_ACI_D_TOC callType ) +#endif /* ifdef NO_ASCIIZ */ +{ + T_CLPTY_PRM *cldPty; /* holds calling party parameter */ + T_ACI_RETURN retVal; /* holds function return value */ + UBYTE srchRslt = 0; /* holds search result */ + T_PHB_RECORD phbNtry; /* holds phonebook entry */ + T_PHB_TYPE slctPHB; /* holds selected phonebook */ + T_ACI_PB_TEXT *dial_name; +#ifndef NO_ASCIIZ + T_ACI_PB_TEXT dialname; +#endif /* #ifndef NO_ASCIIZ */ + + ACI_MALLOC (cldPty, sizeof (T_CLPTY_PRM)); + + TRACE_FUNCTION ("sAT_Dm()"); +/* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + RETURN( AT_FAIL ) + } + + /* init cldPty */ + cmhCC_init_cldPty( cldPty ); + +#ifdef NO_ASCIIZ + dial_name = str; +#else /* #ifdef NO_ASCIIZ */ + dial_name = &dialname; + + if ( str NEQ NULL ) + { + USHORT len = (USHORT)strlen( str ); + + cmh_cvtToDefGsm ( str, (CHAR*)dial_name->data, &len ); + dial_name->cs = CS_Sim; + dial_name->len = (UBYTE)len; + } + else + { + dial_name->cs = CS_NotPresent; + dial_name->len = 0; + } +#endif /* #ifdef NO_ASCIIZ */ + +/* + *------------------------------------------------------------------- + * check for name search + *------------------------------------------------------------------- + */ + if( dial_name->len NEQ 0 ) + { + if( psaCC_phbSrchName( srcId, dial_name, cldPty ) ) + RETURN( cmhCC_Dial( srcId, cldPty, clirOvrd, cugCtrl, callType )) + + else + { + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_NotFound ); + RETURN( AT_FAIL ) + } + } + +/* + *------------------------------------------------------------------- + * check for index read + *------------------------------------------------------------------- + */ +#ifdef NO_ASCIIZ + if( ( !str OR !str->len ) AND index NEQ ACI_NumParmNotPresent ) +#else /* #ifdef NO_ASCIIZ */ + if( !str AND index NEQ ACI_NumParmNotPresent ) +#endif /* #ifdef NO_ASCIIZ */ + { + if( !cmhPHB_cvtPhbType ((( mem EQ PB_STOR_NotPresent )? + cmhPrm[srcId].phbCmdPrm.cmhStor : mem), &slctPHB )) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + RETURN( AT_FAIL ) + } + +#ifdef TI_PS_FFS_PHB + if (pb_read_record (slctPHB, index, &phbNtry) EQ PHB_OK) +#else + if( pb_read_phys_record( slctPHB, index, &phbNtry ) + EQ PHB_OK ) +#endif + { + cmhPHB_getAdrStr( cldPty->num, sizeof (cldPty->num) - 1, + phbNtry.number, phbNtry.len ); + + cmh_demergeTOA ( phbNtry.ton_npi, &cldPty->ton, &cldPty->npi ); + RETURN( cmhCC_Dial( srcId, cldPty, clirOvrd, cugCtrl, callType )) + } + else + { + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_InvIdx ); + RETURN( AT_FAIL ) + } + } + RETURN( AT_FAIL ) + + /* The one and only exit out of this function to avoid memory leaks */ +cleanup_exit: + ACI_MFREE (cldPty); + return retVal; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_Dn | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the D AT command + which is responsible to originate a call to a given phone + number. The D command starts to establish a new call if no + call is currently active. Otherwise if a call is in active + state the D command starts to modify the active call. If the + call mode set by the +CMOD command indicates a single call + no modification takes place and the D command returns with + a fail. + + <number> : phone number. + <clirOvrd>: CLIR override + <cugCtrl> : CUG control + <callType>: call type +*/ + +GLOBAL T_ACI_RETURN sAT_Dn ( T_ACI_CMD_SRC srcId, + CHAR * number, + T_ACI_D_CLIR_OVRD clirOvrd, + T_ACI_D_CUG_CTRL cugCtrl, + T_ACI_D_TOC callType ) +{ + CHAR trace_number_buffer[80]; + T_CLPTY_PRM *cldPty = NULL; /* holds calling party parameter */ + T_ACI_RETURN retVal; /* holds function return value */ +#if defined (GPRS) AND defined (DTI) + BOOL gprs_command; + T_ATI_RSLT r_value; +#endif /* GPRS */ + + TRACE_FUNCTION ("sAT_Dn()"); + if (number NEQ NULL) + { + /* char trcBuf[80]; */ + int dst_i; + dst_i = sprintf (trace_number_buffer, "sAT_Dn(): dialled nb="); + strncpy (&trace_number_buffer[dst_i], number, 79-dst_i); + trace_number_buffer[79] = '\0'; + + if (trace_number_buffer[76]) + { + trace_number_buffer[76] = trace_number_buffer[77] = trace_number_buffer[78] = '.'; /* add trailing "..." if string is >=76 */ + } + TRACE_EVENT (trace_number_buffer); + } +/* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + +#if defined (GPRS) AND defined (DTI) + r_value = atGD( number, (UBYTE) srcId, &gprs_command ); + if ( gprs_command EQ TRUE) + { + /* SPR#1983 - SH */ + switch (r_value) + { + case ATI_CMPL: + return AT_CMPL; + + case ATI_EXCT: + return AT_EXCT; + + default: + return AT_FAIL; + } + /* end SPR#1983 */ + } +#endif /* GPRS */ + + ACI_MALLOC (cldPty, sizeof (T_CLPTY_PRM)); + + /* initialize called party parameter */ + if(number NEQ NULL) + { + cmhCC_init_cldPty( cldPty ); + + cmh_bldCalPrms ( number, cldPty ); + } + +/* + *------------------------------------------------------------------- + * start dialling + *------------------------------------------------------------------- + */ + retVal = cmhCC_Dial( srcId, + (number NEQ NULL) ? cldPty : NULL, + clirOvrd, + cugCtrl, + callType ); + ACI_MFREE (cldPty); + return retVal; +} + + +/* initialize cldPty structure */ +GLOBAL void cmhCC_init_cldPty( /*lint -e(578) */T_CLPTY_PRM *cldPty ) +{ + cldPty->num[0] = 0; + cldPty->ton = TON_NOT_PRES; + cldPty->npi = NPI_NOT_PRES; + cldPty->sub[0] = 0; + cldPty->tos = TOS_NOT_PRES; + cldPty->oe = OE_EVEN; +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : cmhCC_CHLD_Serv | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the %CHLD AT command + which is responsible to handle the supplementary services + witin a call. This function is resonsible for the +CHLD + and %CHLD command both. +*/ +LOCAL T_ACI_RETURN cmhCC_CHLD_Serv(T_ACI_CMD_SRC srcId, + T_ACI_CHLD_MOD mode, + CHAR *call) +{ + /* check command source */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + switch( mode ) + { + /* release all held calls, or UDUB for CWA */ + case( CHLD_MOD_RelHldOrUdub ): + return(chld_RelHldOrUdub(srcId)); + + /* release all active calls, and accept held or waiting call */ + case( CHLD_MOD_RelActAndAcpt ): + return(chld_RelActAndAcpt(srcId)); + + /* release a specific active call */ + case( CHLD_MOD_RelActSpec ): + return(chld_RelActSpec(srcId, call)); + + /* place all active calls on hold, and accept held or waiting call */ + case( CHLD_MOD_HldActAndAcpt ): + return(chld_HldActAndAcpt(srcId)); + + /* place all active calls on hold except the specified call */ + case( CHLD_MOD_HldActExc ): + return(chld_HldActExc(srcId, call)); + + /* add a held call to the conversation */ + case( CHLD_MOD_AddHld ): + return(chld_AddHld(srcId)); + + /* explicit call transfer */ + case( CHLD_MOD_Ect ): + return(chld_Ect(srcId)); + + /* activate call completion to busy subscriber */ + case( CHLD_MOD_Ccbs ): + return(chld_Ccbs(srcId)); + + /* place a call on hold */ + case(CHLD_MOD_OnlyHold): + return(chld_OnlyHold(srcId)); + + /* release currently dialling call only */ + case(CHLD_MOD_RelDialCall): + return(chld_RelDialCall(srcId)); + + /* retrive first held call on the list */ + case(CHLD_MOD_RetrieveHoldCall): + return(chld_RetrieveHoldCall(srcId)); + + /* retrieve specific held call */ + case(CHLD_MOD_RetrieveHoldCallSpec): + return(chld_RetrieveHoldCallSpec(srcId, call)); + + /* releases specific call */ + case(CHLD_MOD_RelAnySpec): + return(chld_RelAnySpec(srcId, call)); + + } + /* for unexpected conditions */ + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow ); + return( AT_FAIL ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : cmhCC_Dial | ++--------------------------------------------------------------------+ + + PURPOSE : Start dialling. + +*/ + +/* helper function for delivering delayed rAT_PlusCPMS callback */ +LOCAL UCHAR cmhCC_Dial_delayed (void* arg) +{ + struct cmhCC_Dial_buffer* p = (struct cmhCC_Dial_buffer*) arg; + TRACE_EVENT("delayed delivery of RAT_NO_CARRIER after cmhCC_Dial"); + R_AT( RAT_NO_CARRIER, p->srcId ) ( AT_CMD_D, 0 ); + return FALSE; /* single-shot */ +} + +GLOBAL T_ACI_RETURN cmhCC_Dial ( T_ACI_CMD_SRC srcId, + /*lint -e(578) */ T_CLPTY_PRM *cldPty, + T_ACI_D_CLIR_OVRD clirOvrd, + T_ACI_D_CUG_CTRL cugCtrl, + T_ACI_D_TOC callType ) +{ + SHORT cId, newId; /* holds call id */ + T_CC_CMD_PRM * pCCCmdPrm; /* points to CC command parameters */ + T_ACI_RETURN retVal; /* holds return value */ + UBYTE prio; /* holds priority of the call */ + USHORT dummy=0; + UBYTE idx; + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + T_ACI_CLOG cmdLog; /* holds logging info */ +#endif + int i; + + TRACE_FUNCTION ("cmhCC_Dial()"); + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + + causeMod = P_CEER_mod; /* Clear module which was set for ceer */ + causeCeer = CEER_NotPresent; /* Clear proprietary cause when at point of dialling. */ +/* + *------------------------------------------------------------------- + * check for an active call + *------------------------------------------------------------------- + */ + + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_ACT, NO_VLD_CT ); + +#ifdef FAX_AND_DATA + + if( cId NEQ NO_ENTRY ) + { + + /* + *----------------------------------------------------------------- + * check call mode to modify the call + *----------------------------------------------------------------- + */ + if( cmhCC_ChckInCallMdfy( cId, AT_CMD_D ) ) + { + cmhCC_flagCall( cId, &(pCCCmdPrm->mltyCncFlg)); + psaCC_ctb(cId)->curCmd = AT_CMD_D; + psaCC_ctb(cId)->curSrc = srcId; + psaCC_ModifyCall(cId); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + /* log command */ + cmdLog.atCmd = AT_CMD_D; + cmdLog.cmdType = CLOG_TYPE_Set; + cmdLog.retCode = AT_EXCT; + cmdLog.cId = cId+1; + cmdLog.sId = ACI_NumParmNotPresent; + cmdLog.cmdPrm.sD.srcId = srcId; + cmdLog.cmdPrm.sD.number = NULL; + cmdLog.cmdPrm.sD.clirOvrd = clirOvrd; + cmdLog.cmdPrm.sD.cugCtrl = cugCtrl; + cmdLog.cmdPrm.sD.callType = callType; +#ifdef SIM_TOOLKIT + cmdLog.cmdPrm.sD.simCallCtrl= D_SIMCC_NOT_ACTIVE; +#endif /* SIM_TOOLKIT */ + + rAT_PercentCLOG( &cmdLog ); +#endif + + return( AT_EXCT ); + } + } + +#endif /* of #ifdef FAX AND_DATA */ + + if( cldPty EQ NULL ) + { + TRACE_EVENT("ERROR: cldPty is NULL"); + + if (callType EQ D_TOC_Voice) + return(AT_CMPL); + else + { + if (!cmh_set_delayed_call (cmhCC_Dial_delayed, &cmhCC_Dial_buffer)) + return AT_BUSY; + + cmhCC_Dial_buffer.srcId = srcId; + + TRACE_EVENT("delayed return requested: 100 ms"); + cmh_start_delayed_call (100); + + return(AT_EXCT); + } + } + +/* + *------------------------------------------------------------------- + * determine call priority + *------------------------------------------------------------------- + */ + if (cmhMM_ChkIgnoreECC(cldPty->num)) + { + prio = PRIO_NORM_CALL; + TRACE_EVENT("cmhCC_Dial(): ECC check is ignored"); + } + else + { + TRACE_EVENT("cmhCC_Dial(): ECC check is coninued"); + prio = psaCC_phbSrchECC ( cldPty->num, TRUE ); + } + +/* + *------------------------------------------------------------------- + * check fixed dialing phonebook if enabled + *------------------------------------------------------------------- + */ + if( prio EQ PRIO_NORM_CALL AND + (simShrdPrm.crdFun EQ SIM_FDN_ENABLED OR + simShrdPrm.crdFun EQ SIM_FDN_BDN_ENABLED) ) + { + if( ksd_isFDNCheckSeq ( cldPty->num ) ) + { + if(!psaCC_phbNtryFnd( FDN, cldPty )) + { + TRACE_EVENT ( "FDN check failed" ); + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_FdnCheck ); + return( AT_FAIL ); + } + } + } + +/* + *------------------------------------------------------------------- + * Add Number or Sequence to LDN phonebook + * This has to be done prior keystrokes to allow adding some special + * sequences for dialing purpose with prepaid SIMs when roaming (USSD callback) + *------------------------------------------------------------------- + */ + if (prio NEQ PRIO_EMERG_CALL) /* only normal calls are added to the LDN PB */ + { + if(ksd_isLDNWriteCheckSeq(cldPty->num)) /* check whether the string needs to be written to LDN?*/ + { + /* A call table entry does not exist here yet */ + psaCC_phbAddNtry( LDN, NO_ENTRY, CT_MOC, cldPty ); /* add call to LDN PB */ + } + } + +/* + *------------------------------------------------------------------- + * check for a keystroke sequence + *------------------------------------------------------------------- + */ + + if(prio NEQ PRIO_EMERG_CALL) + { + retVal = cmhCC_chkKeySeq ( srcId, + cldPty, + &callType, + &clirOvrd, + CC_SIM_YES ); + + if( retVal NEQ AT_CONT ) + return( retVal ); + } + else if (strlen(cldPty->num) > 4) + { + /* decode clirOvrd in case of ECC + since cmhCC_chkKeySeq is not aware of ECC */ + + if ( !strncmp(cldPty->num,"*31#",4) OR /* KSD_SUPPRESS_CLIR */ + !strncmp(cldPty->num,"#31#",4) ) /* KSD_INVOKE_CLIR */ + { + CHAR *p1, *p2; + + if (*cldPty->num EQ '*') + clirOvrd = D_CLIR_OVRD_Supp; + else + clirOvrd = D_CLIR_OVRD_Invoc; + /* and remove clirOvrd from dial num */ + for (p1=cldPty->num, p2=cldPty->num+4; /*lint -e720 */ *p1++ = *p2++; ) + ; + } + } + + +/* + *------------------------------------------------------------------- + * check for a short string sequence: should also be USSD (see 02.30 chptr 4.5.3.2) + *------------------------------------------------------------------- + */ + if( ( prio EQ PRIO_NORM_CALL ) AND ( !ksd_isBCDForUSBand(cldPty->num) ) ) + { + retVal = cmhCC_chkShortString (srcId, cId, cldPty); + if (retVal NEQ AT_EXCT) + { + return (retVal); + } + } + +/* + *------------------------------------------------------------------- + * check redialing + *------------------------------------------------------------------- + */ + /* stop redialling timer if necessary */ + if (rdlPrm.rdlcId NEQ NO_ENTRY) + { + TIMERSTOP(ACI_REPEAT_HND); + if(rdlPrm.rdlcId NEQ -1) + {/* clear call id entry in call table if marked as used */ + psaCC_FreeCtbNtry (rdlPrm.rdlcId); + } + for(i = 0; i < CMD_SRC_MAX; i++) + { + R_AT(RAT_RDL, i)(REDIAL_STOP); + } + /* reset some redial parameter */ + rdlPrm.rdlcId = NO_ENTRY; + } + +/* + *------------------------------------------------------------------- + * continue dialing + *------------------------------------------------------------------- + */ + newId = psaCC_ctbNewEntry(); + + if( newId EQ NO_ENTRY ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_CallTabFull ); + return( AT_FAIL ); /* call table full */ + } + + if( cId NEQ NO_ENTRY ) + { + + /* + *----------------------------------------------------------------- + * check if there is already a call on hold + *----------------------------------------------------------------- + */ + if( psaCC_ctbFindCall( NO_VLD_OWN, CS_HLD, NO_VLD_CT ) NEQ NO_ENTRY ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_OneCallOnHold ); + psaCC_FreeCtbNtry (newId); + return( AT_FAIL ); + } + + /* + *----------------------------------------------------------------- + * check to put active call on hold, if it is no data call and not + * an emergency call + *----------------------------------------------------------------- + */ + if( psaCC_ctb(cId)->prio EQ PRIO_NORM_CALL AND + cmhCC_getcalltype(cId) EQ VOICE_CALL ) + { + if( pCCCmdPrm->mltyCncFlg NEQ 0 ) + { + psaCC_FreeCtbNtry (newId); + return( AT_BUSY ); + } + } + else + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_CallTypeNoHold ); + psaCC_FreeCtbNtry (newId); + return( AT_FAIL ); + } + } + +/* + *------------------------------------------------------------------- + * setup call parameters + *------------------------------------------------------------------- + */ + cmhCC_chkDTMFDig ( cldPty->num, newId, dummy, TRUE ); + + retVal = cmhCC_fillSetupPrm ( newId, srcId, cldPty, NULL, prio, + clirOvrd, cugCtrl, callType ); + if( retVal NEQ AT_CMPL ) + { + psaCC_FreeCtbNtry (newId); + return( retVal ); + } + +/* + *------------------------------------------------------------------- + * check number against black list entries + *------------------------------------------------------------------- + */ + if(rdlPrm.rdlMod EQ AUTOM_REPEAT_ON) + { + if(cmhCC_redialChkBlackl(newId) NEQ AT_CMPL) + { + psaCC_FreeCtbNtry (newId); + return( AT_FAIL); + } + } +/* + *----------------------------------------------------------------- + * declare call table entry as used and the owner of the call + *----------------------------------------------------------------- + */ + psaCC_ctb(newId)->calType = CT_MOC; + psaCC_ctb(newId)->calOwn = srcId; + psaCC_ctb(newId)->curCmd = AT_CMD_D; + psaCC_ctb(newId)->curSrc = srcId; + +/* + *------------------------------------------------------------------- + * check for call control by SIM toolkit + *------------------------------------------------------------------- + */ +#ifdef SIM_TOOLKIT + + if ( prio NEQ PRIO_EMERG_CALL ) /* don't send emergency calls to */ + { /* SIM toolkit */ + if ( !ksd_isFDNCheckSeq ( cldPty-> num ) ) + ; /* bypass *#06# from CntrlBySIM */ + else + { + retVal = cmhSAT_CalCntrlBySIM( newId ); + + if( retVal NEQ AT_CMPL ) + { +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.atCmd = AT_CMD_D; + cmdLog.cmdType = CLOG_TYPE_Set; + cmdLog.retCode = AT_EXCT; + cmdLog.cId = newId+1; + cmdLog.sId = ACI_NumParmNotPresent; + cmdLog.cmdPrm.sD.srcId = srcId; + cmdLog.cmdPrm.sD.number = cldPty->num; + cmdLog.cmdPrm.sD.clirOvrd = clirOvrd; + cmdLog.cmdPrm.sD.cugCtrl = cugCtrl; + cmdLog.cmdPrm.sD.callType = callType; + cmdLog.cmdPrm.sD.simCallCtrl= D_SIMCC_ACTIVE_CHECK; + + rAT_PercentCLOG( &cmdLog ); +#endif + return( retVal ); + } + } + + } + +#endif + + if( cId NEQ NO_ENTRY ) + { + /* put an active call on hold prior to set up the new call */ + CHLDaddInfo = CHLD_ADD_INFO_DIAL_CAL; + pCCCmdPrm -> CHLDmode = CHLD_MOD_HldActDial; + + cmhCC_HoldCall(cId, srcId, AT_CMD_D); + + /* flag newId to start the call once active call has been held */ + cmhCC_flagCall( newId, &(pCCCmdPrm->mltyCncFlg)); + } + else + { + /* start a new call */ + cmhCC_flagCall( newId, &(pCCCmdPrm->mltyCncFlg)); + + psaCC_NewCall(newId); + /* call progress information */ + for(idx = 0; idx < CMD_SRC_MAX; idx++ ) + { + R_AT(RAT_CPI, idx)( newId+1, + CPI_MSG_MO_Setup, + (psaCC_ctb(newId)->inBndTns)? CPI_IBT_True: CPI_IBT_False, + (ccShrdPrm.TCHasg)? CPI_TCH_True: CPI_TCH_False, + psaCC_ctb(newId)->curCs); + } + } + +/* log command */ +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.atCmd = AT_CMD_D; + cmdLog.cmdType = CLOG_TYPE_Set; + cmdLog.retCode = AT_EXCT; + cmdLog.cId = newId+1; + cmdLog.sId = ACI_NumParmNotPresent; + cmdLog.cmdPrm.sD.srcId = srcId; + cmdLog.cmdPrm.sD.number = cldPty->num; + cmdLog.cmdPrm.sD.clirOvrd = clirOvrd; + cmdLog.cmdPrm.sD.cugCtrl = cugCtrl; + cmdLog.cmdPrm.sD.callType = callType; +#ifdef SIM_TOOLKIT + cmdLog.cmdPrm.sD.simCallCtrl= D_SIMCC_NOT_ACTIVE; +#endif /* SIM_TOOLKIT */ + + rAT_PercentCLOG( &cmdLog ); + +#endif + + return( AT_EXCT ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_H | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the H AT command + which is responsible to terminate or modify a call. + + 1. The function searches for an active call. If this + call is modifiable, it will be modified and the function + returns. + 2. Then the function searches for a call that is in the + disconnect request state and indicates CCBS possibility, + this call will be finally released. + 3. If enabled the next search looks for a pending SAT call. + If such a call is found the call is rejected and the SIM card + will be informed. + 4. The next step is to clear all calls of the call table + exept a waiting call. The function returns if at least one + call could be found. + 5. If no call was found, the function searches for a waiting + call. If a waiting call was found, the call will be + terminated declaring the user as busy. + 6. If none of the above situations match, the function + returns with a fail. + +*/ + +GLOBAL T_ACI_RETURN sAT_H ( T_ACI_CMD_SRC srcId ) +{ + SHORT cId; /* holds call id */ + SHORT waitId = NO_ENTRY; /* holds call waiting id */ + T_CC_CMD_PRM * pCCCmdPrm; /* points to CC command parameters */ + UBYTE idx; +#if defined (GPRS) AND defined (DTI) + T_ACI_RETURN ret_value; +#endif /* GPRS */ + int i; + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + T_ACI_CLOG cmdLog; /* holds logging info */ +#endif + + TRACE_FUNCTION ("sAT_H()"); + + /* check command source */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + + +#if defined (GPRS) AND defined (DTI) + /* handle command for GPRS */ + if ( TRUE EQ cmhSM_sAT_H( srcId, &ret_value ) ) + return ret_value; +#endif /* GPRS */ + +/* prepare log command */ +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.atCmd = AT_CMD_H; + cmdLog.cmdType = CLOG_TYPE_Set; + cmdLog.retCode = AT_EXCT; + cmdLog.sId = ACI_NumParmNotPresent; + cmdLog.cmdPrm.sH.srcId = srcId; +#endif + +#ifdef ACI /* for ATI only version */ + cmhMMI_handleAudioTone ( AT_CMD_H, RAT_OK, CPI_MSG_NotPresent ); +#endif + +/* + *------------------------------------------------------------------- + * find an active call and check call mode in case of + * in-call modification + *------------------------------------------------------------------- + */ +#if defined (FAX_AND_DATA) AND defined (DTI) + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_ACT, NO_VLD_CT ); + + if( cId NEQ NO_ENTRY AND + cmhCC_ChckInCallMdfy( cId, AT_CMD_H ) ) + { + switch( cmhCC_getcalltype(cId) ) + { + case( TRANS_CALL ): + ccShrdPrm.datStat = DS_MDF_REQ; + cmhTRA_Deactivate(); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + rAT_PercentCLOG( &cmdLog ); +#endif + return( AT_EXCT ); + + case( NON_TRANS_CALL ): + ccShrdPrm.datStat = DS_MDF_REQ; + cmhL2R_Deactivate(); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + rAT_PercentCLOG( &cmdLog ); +#endif + return( AT_EXCT ); + +#ifdef FF_FAX + case( FAX_CALL ): + ccShrdPrm.datStat = DS_MDF_REQ; + cmhT30_Deactivate (); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + rAT_PercentCLOG( &cmdLog ); +#endif + return( AT_EXCT ); +#endif /* FF_FAX */ + } + } +#endif /* FAX_AND_DATA */ + + +/* + *------------------------------------------------------------------- + * check for a call with CCBS possible + *------------------------------------------------------------------- + */ + if( pCCCmdPrm -> mltyDscFlg NEQ 0 ) + return( AT_BUSY ); + +/* + *------------------------------------------------------------------- + * check for a redial call + *------------------------------------------------------------------- + */ + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_ACT_REQ, CT_MOC_RDL); + + if( cId NEQ NO_ENTRY ) + { + psaCC_ctb(cId)->calType = CT_MOC; + + if(rdlPrm.rdlMod EQ AUTOM_REPEAT_ON) + { + for(i = 0; i < CMD_SRC_MAX; i++) + { + R_AT(RAT_RDL, i)(REDIAL_STOP); + } + rdlPrm.rdlcId = NO_ENTRY; + } + psaCC_ctb(cId)->nrmCs = MNCC_CAUSE_CALL_CLEAR; + psaCC_ClearCall (cId); + psaCC_FreeCtbNtry (cId); + return( AT_CMPL ); + } + else + {/* redial timer is running */ + if ((rdlPrm.rdlMod EQ AUTOM_REPEAT_ON) AND (rdlPrm.rdlcId NEQ NO_ENTRY)) + { + if(rdlPrm.rdlcId NEQ -1) + {/* clear call id entry in call table if marked as used */ + psaCC_FreeCtbNtry (rdlPrm.rdlcId); + } + for(i = 0; i < CMD_SRC_MAX; i++) + { + R_AT(RAT_RDL, i)(REDIAL_STOP); + } + /* reset some redial parameter */ + rdlPrm.rdlcId = NO_ENTRY; + return( AT_CMPL ); + } + } + + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_ACT_REQ, CT_MOC ); + + if (cId EQ NO_ENTRY) + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_DSC_REQ, CT_MOC ); /* also search for calls in disconnect state */ + + if( cId NEQ NO_ENTRY ) + { + if( psaCC_ctb(cId)->CCBSstat EQ CCBSS_PSSBL ) + { + pCCCmdPrm -> mltyDscFlg = 0; + + cmhCC_flagCall( cId, &(pCCCmdPrm -> mltyDscFlg)); + psaCC_ctb(cId)->nrmCs = MNCC_CAUSE_CALL_CLEAR; + psaCC_ctb(cId)->curCmd = AT_CMD_H; + psaCC_ctb(cId)->curSrc = srcId; + psaCC_ClearCall (cId); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + rAT_PercentCLOG( &cmdLog ); +#endif + return( AT_EXCT ); + } + } + +/* + *------------------------------------------------------------------- + * check for a CCBS recall + *------------------------------------------------------------------- + */ + cId = psaCC_ctbFindCall( OWN_NONE, CS_ACT_REQ, CT_NI_MOC ); + + if( cId NEQ NO_ENTRY ) + { + psaCC_ctb(cId)->nrmCs = MNCC_CAUSE_CALL_REJECT; + psaCC_ClearCall (cId); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + cmdLog.retCode = AT_CMPL; + rAT_PercentCLOG( &cmdLog ); +#endif + + psaCC_FreeCtbNtry (cId); + return( AT_CMPL ); + } + +/* + *------------------------------------------------------------------- + * check for a pending SAT call + *------------------------------------------------------------------- + */ +#ifdef SIM_TOOLKIT + /* triggered by SETUP CALL command */ + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_SAT_REQ, NO_VLD_CT ); +#ifdef FF_SAT_E + if( cId EQ NO_ENTRY ) + { + /* triggered by OPEN CHANNEL command */ + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_SAT_CSD_REQ, NO_VLD_CT ); + } +#endif /* FF_SAT_E */ + + if( cId NEQ NO_ENTRY ) + { + if( psaCC_ctb(cId)->SATinv ) + cmhSAT_UserRejCall(psaCC_ctb(cId)->calStat); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + cmdLog.retCode = AT_CMPL; + rAT_PercentCLOG( &cmdLog ); +#endif + + psaCC_FreeCtbNtry (cId); + return( AT_CMPL ); + } +#if defined (GPRS) AND defined (FF_SAT_E) AND defined (DTI) + /* check for pending SAT GPRS context */ + else + { + if( cmhSAT_OpChnGPRSPend(INVALID_CID, OPCH_WAIT_CNF)) + { + cmhSAT_UserRejCntxt(); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + cmdLog.retCode = AT_CMPL; + rAT_PercentCLOG( &cmdLog ); +#endif + return( AT_CMPL ); + } + } +#endif /* GPRS AND FF_SAT_E */ +#endif /* SIM_TOOLKIT */ + psaCC_FreeCtbNtry (cId); + +/* + *------------------------------------------------------------------- + * clear all calls except a waiting call + *------------------------------------------------------------------- + */ + pCCCmdPrm -> mltyDscFlg = 0; + + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + cmhCC_ClearCall( cId, MNCC_CAUSE_CALL_CLEAR, srcId, AT_CMD_H, &waitId ); + } + + if( pCCCmdPrm -> mltyDscFlg ) + { +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + rAT_PercentCLOG( &cmdLog ); +#endif + return( AT_EXCT ); + } + +/* + *------------------------------------------------------------------- + * disconnect a waiting call with user determined user busy + *------------------------------------------------------------------- + */ + if( waitId NEQ NO_ENTRY ) + { + cmhCC_flagCall( waitId, &(pCCCmdPrm -> mltyDscFlg)); + psaCC_ctb(waitId)->nrmCs = MNCC_CAUSE_USER_BUSY; + psaCC_ctb(waitId)->curCmd = AT_CMD_H; + psaCC_ctb(waitId)->curSrc = srcId; + psaCC_ClearCall (waitId); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = waitId+1; + rAT_PercentCLOG( &cmdLog ); +#endif + +#ifdef FF_ATI + io_setRngInd (IO_RING_OFF, CRING_TYP_NotPresent, CRING_TYP_NotPresent ); /* V.24 Ring Indicator Line */ +#endif + for( idx = 0; idx < CMD_SRC_MAX; idx++ ) + { + R_AT( RAT_CRING_OFF, idx )( waitId+1 ); + } + return( AT_EXCT ); + } + +/* + *------------------------------------------------------------------- + * nothing to act on + *------------------------------------------------------------------- + */ + return( AT_CMPL ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_PlusCHUP | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the +CHUP AT command + which is responsible to terminate a call. + + 1. The next step is to clear all calls of the call table + exept a waiting call. The function returns if at least one + call could be found. + 2. If no call was found, the function searches for a waiting + call. If a waiting call was found, the call will be + terminated declaring the user as busy. + 3. If none of the above situations match, the function + returns with a fail. + +*/ + +GLOBAL T_ACI_RETURN sAT_PlusCHUP ( T_ACI_CMD_SRC srcId ) +{ + SHORT cId; /* holds call id */ + SHORT waitId = NO_ENTRY; /* holds call waiting id */ + T_CC_CMD_PRM * pCCCmdPrm; /* points to CC command parameters */ + UBYTE idx; + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + T_ACI_CLOG cmdLog; /* holds logging info */ +#endif + int i; + + TRACE_FUNCTION ("sAT_CHUP()"); + +/* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + +/* + *------------------------------------------------------------------- + * prepare log command + *------------------------------------------------------------------- + */ +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.atCmd = AT_CMD_CHUP; + cmdLog.cmdType = CLOG_TYPE_Set; + cmdLog.retCode = AT_EXCT; + cmdLog.sId = ACI_NumParmNotPresent; + cmdLog.cmdPrm.sCHUP.srcId = srcId; +#endif +/* + *------------------------------------------------------------------- + * check for a redial call + *------------------------------------------------------------------- + */ + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_ACT_REQ, CT_MOC_RDL); + + if( cId NEQ NO_ENTRY ) + { + psaCC_ctb(cId)->calType = CT_MOC; + if(rdlPrm.rdlMod EQ AUTOM_REPEAT_ON) + { + for(i = 0; i < CMD_SRC_MAX; i++) + { + R_AT(RAT_RDL, i)(REDIAL_STOP); + } + rdlPrm.rdlcId = NO_ENTRY; + } + } + else + {/* redial timer is running */ + if ((rdlPrm.rdlMod EQ AUTOM_REPEAT_ON) AND (rdlPrm.rdlcId NEQ NO_ENTRY)) + { + if(rdlPrm.rdlcId NEQ -1) + {/* clear call id entry in call table if marked as used */ + psaCC_FreeCtbNtry (rdlPrm.rdlcId); + } + for(i = 0; i < CMD_SRC_MAX; i++) + { + R_AT(RAT_RDL, i)(REDIAL_STOP); + } + /* reset some redial parameter */ + rdlPrm.rdlcId = NO_ENTRY; + return( AT_CMPL ); + } + } +/* + *------------------------------------------------------------------- + * check for a pending SAT call + *------------------------------------------------------------------- + */ +#ifdef SIM_TOOLKIT + /* triggered by SETUP CALL command */ + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_SAT_REQ, NO_VLD_CT ); + +#ifdef FF_SAT_E + if( cId EQ NO_ENTRY ) + { + /* triggered by OPEN CHANNEL command */ + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_SAT_CSD_REQ, NO_VLD_CT ); + } +#endif + + if( cId NEQ NO_ENTRY ) + { + if( psaCC_ctb(cId)->SATinv ) + cmhSAT_UserRejCall(psaCC_ctb(cId)->calStat); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + cmdLog.retCode = AT_CMPL; + rAT_PercentCLOG( &cmdLog ); +#endif + + psaCC_FreeCtbNtry (cId); + return( AT_CMPL ); + } +#if defined (GPRS) AND defined (FF_SAT_E) AND defined (DTI) + /* check for pending SAT GPRS context */ + else + { + if( cmhSAT_OpChnGPRSPend(INVALID_CID, OPCH_WAIT_CNF)) + { + cmhSAT_UserRejCntxt(); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + cmdLog.retCode = AT_CMPL; + rAT_PercentCLOG( &cmdLog ); +#endif + return( AT_CMPL ); + } + } +#endif /* GPRS AND FF_SAT_E */ +#endif /* SIM_TOOLKIT */ + psaCC_FreeCtbNtry (cId); + +/* + *------------------------------------------------------------------- + * clear only active call + *------------------------------------------------------------------- + */ + if( pCCCmdPrm -> mltyDscFlg NEQ 0 ) + return( AT_BUSY ); + + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_ACT, NO_VLD_CT); + + if( cId NEQ NO_ENTRY ) + { + cmhCC_ClearCall(cId, MNCC_CAUSE_CALL_CLEAR, srcId, AT_CMD_CHUP, &waitId ); + } + + if( pCCCmdPrm -> mltyDscFlg ) + { +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + rAT_PercentCLOG( &cmdLog ); +#endif + return( AT_EXCT ); + } + +/* + *------------------------------------------------------------------- + * disconnect a waiting call with user determined user busy + *------------------------------------------------------------------- + */ + if( waitId NEQ NO_ENTRY ) + { + cmhCC_flagCall( waitId, &(pCCCmdPrm -> mltyDscFlg)); + psaCC_ctb(waitId)->nrmCs = MNCC_CAUSE_USER_BUSY; + psaCC_ctb(waitId)->curCmd = AT_CMD_CHUP; + psaCC_ctb(waitId)->curSrc = srcId; + psaCC_ClearCall (waitId); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = waitId+1; + rAT_PercentCLOG( &cmdLog ); +#endif + +#ifdef FF_ATI + io_setRngInd ( IO_RING_OFF, CRING_TYP_NotPresent, CRING_TYP_NotPresent ); /* V.24 Ring Indicator Line */ +#endif + + for( idx = 0; idx < CMD_SRC_MAX; idx++ ) + { + R_AT( RAT_CRING_OFF, idx )( waitId+1 ); + } + return( AT_EXCT ); + } + +/* + *------------------------------------------------------------------- + * nothing to act on + *------------------------------------------------------------------- + */ + return( AT_CMPL ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_A | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the A AT command + which is responsible to accept an incoming call. The A + command accepts an incoming call if no call is currently + active. Otherwise if a call is in active state the A command + starts to modify the active call. If the call mode set by + the +CMOD command indicates a single call no modification + takes place and the A command returns with a fail. + +*/ + +// CC test 0319 +extern void CongiureGPIO_Internal(int GpioPin); +extern void HighGPIO(int GpioPin); +extern void LowGPIO(int GpioPin); +// end + +GLOBAL T_ACI_RETURN sAT_A ( T_ACI_CMD_SRC srcId ) +{ + SHORT cId; /* holds call id */ + T_CC_CMD_PRM * pCCCmdPrm; /* points to CC command parameters */ + +#if defined (GPRS) AND defined (DTI) + T_ACI_RETURN ret_value; +#endif /* GPRS */ + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + T_ACI_CLOG cmdLog; /* holds logging info */ +#endif + +// CC test 0319 +// HighGPIO(1); +// end + + TRACE_FUNCTION ("sAT_A()"); + +/* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + +/* + *------------------------------------------------------------------- + * handle command for GPRS + *------------------------------------------------------------------- + */ +#if defined (GPRS) AND defined (DTI) + + if ( TRUE EQ cmhSM_sAT_A( srcId, &ret_value ) ) + return ret_value; + +#endif /* GPRS */ + +/* + *------------------------------------------------------------------- + * prepare log command + *------------------------------------------------------------------- + */ +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.atCmd = AT_CMD_A; + cmdLog.cmdType = CLOG_TYPE_Set; + cmdLog.retCode = AT_EXCT; + cmdLog.sId = ACI_NumParmNotPresent; + cmdLog.cmdPrm.sA.srcId = srcId; +#endif + +/* + *------------------------------------------------------------------- + * check for an active call + *------------------------------------------------------------------- + */ +#ifdef FAX_AND_DATA + + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_ACT, NO_VLD_CT ); + + if( cId NEQ NO_ENTRY ) + { + + /* + *----------------------------------------------------------------- + * check call mode to modify the call + *----------------------------------------------------------------- + */ + if( cmhCC_ChckInCallMdfy( cId, AT_CMD_A ) ) + { + cmhCC_flagCall( cId, &(pCCCmdPrm->mltyCncFlg)); + psaCC_ctb(cId)->curCmd = AT_CMD_A; + psaCC_ctb(cId)->curSrc = srcId; + psaCC_ModifyCall(cId); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + rAT_PercentCLOG( &cmdLog ); +#endif + return( AT_EXCT ); + } + /* + *---------------------------------------------------------------------------------- + * ATA can be used to answer the second SAT call when the first call is active + *---------------------------------------------------------------------------------- + */ +#ifdef SIM_TOOLKIT + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_SAT_REQ, NO_VLD_CT ); +#ifdef FF_SAT_E + if( cId EQ NO_ENTRY ) + { + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_SAT_CSD_REQ, NO_VLD_CT ); + } +#endif /* FF_SAT_E */ + if( cId EQ NO_ENTRY ) + { + TRACE_FUNCTION ("Already a call is active !!!"); + return( AT_FAIL); + } +#else + /* Added Below Two lines to fix ACI-SPR-22325*/ + TRACE_FUNCTION ("Already a call is active !!!"); + return( AT_FAIL ); +#endif + } +#endif /* of #ifdef FAX_AND_DATA */ + + +/* + *------------------------------------------------------------------- + * check for an incoming call to accept + *------------------------------------------------------------------- + */ + if( pCCCmdPrm -> mltyCncFlg NEQ 0 ) + + return( AT_BUSY ); + + cId = psaCC_ctbFindCall( OWN_NONE, CS_ACT_REQ, CT_MTC ); + + if( cId NEQ NO_ENTRY ) + { + /* accept the call */ + cmhCC_flagCall( cId, &(pCCCmdPrm->mltyCncFlg)); + + cmhCC_AcceptCall(cId, srcId, AT_CMD_A); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + rAT_PercentCLOG( &cmdLog ); +#endif + return( AT_EXCT ); + } + +/* + *------------------------------------------------------------------- + * check for a CCBS recall condition + *------------------------------------------------------------------- + */ + cId = psaCC_ctbFindCall( OWN_NONE, CS_ACT_REQ, CT_NI_MOC ); + + if( cId NEQ NO_ENTRY ) + { + /* accept the call */ + { + cmhCC_flagCall( cId, &(pCCCmdPrm->mltyCncFlg)); + + cmhCC_NewCall(cId, srcId, AT_CMD_A); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + rAT_PercentCLOG( &cmdLog ); +#endif + return( AT_EXCT ); + } + } + +/* + *------------------------------------------------------------------- + * check for a pending SAT call + *------------------------------------------------------------------- + */ +#ifdef SIM_TOOLKIT + /* triggered by SETUP CALL command */ + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_SAT_REQ, NO_VLD_CT ); + +#ifdef FF_SAT_E + if( cId EQ NO_ENTRY ) + /* triggered by OPEN CHANNEL command */ + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_SAT_CSD_REQ, NO_VLD_CT ); +#endif /* FF_SAT_E */ + + if( cId NEQ NO_ENTRY ) + { + if( psaCC_ctb(cId)->SATinv ) + { + if( !cmhSAT_UserAcptCall( cId, (UBYTE)srcId ) ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_CmdDetailsSAT ); + return( AT_FAIL ); + } + } + else + { + cmhCC_flagCall( cId, &(pCCCmdPrm->mltyCncFlg)); + cmhCC_NewCall(cId, srcId, AT_CMD_A); + } + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + rAT_PercentCLOG( &cmdLog ); +#endif + + return( AT_EXCT ); + } +#if defined (GPRS) AND defined (FF_SAT_E) AND defined (DTI) + else + { + /* check for a pending SAT GPRS channel */ + if( cmhSAT_OpChnGPRSPend(INVALID_CID, OPCH_WAIT_CNF)) + { + if( !cmhSAT_UserAcptCntxt( (UBYTE)srcId ) ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_CmdDetailsSAT ); + return( AT_FAIL ); + } + return( AT_EXCT ); + } + } +#endif /* GPRS AND FF_SAT_E */ +#endif /* SIM_TOOLKIT */ + + +/* + *------------------------------------------------------------------- + * call not found + *------------------------------------------------------------------- + */ + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_CallNotFound ); + return( AT_FAIL ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_PlusCLIR | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the +CLIR AT command + which is responsible to enable or disable the presentation + of the own calling id for mobile originated calls. + +*/ + +GLOBAL T_ACI_RETURN sAT_PlusCLIR ( T_ACI_CMD_SRC srcId, + T_ACI_CLIR_MOD mode ) +{ + T_CC_CMD_PRM * pCCCmdPrm; /* points to CC command parameters */ + + TRACE_FUNCTION ("sAT_PlusCLIR()"); + +/* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + +/* + *------------------------------------------------------------------- + * process the mode parameter + *------------------------------------------------------------------- + */ + switch( mode ) + { + case( CLIR_MOD_NotPresent ): + break; + + case( CLIR_MOD_Subscript ): + case( CLIR_MOD_Invoc ): + case( CLIR_MOD_Supp ): + pCCCmdPrm -> CLIRmode = mode; + break; + + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + return( AT_CMPL ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_PlusCMOD | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the +CMOD AT command + which is responsible to set the mode for mobile originated + calls. + +*/ + +GLOBAL T_ACI_RETURN sAT_PlusCMOD ( T_ACI_CMD_SRC srcId, + T_ACI_CMOD_MOD mode ) +{ + TRACE_FUNCTION ("sAT_PlusCMOD()"); + + /* check command source */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + /* process the mode parameter */ + switch( mode ) + { + case( CMOD_MOD_NotPresent ): + break; + + case( CMOD_MOD_Single ): + +#ifdef FAX_AND_DATA + case( CMOD_MOD_VoiceFax ): + case( CMOD_MOD_VoiceDat ): + case( CMOD_MOD_VoiceFlwdDat ): +#endif /* of #ifdef FAX_AND_DATA */ + + ccShrdPrm.CMODmode = mode; + break; + + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + return( AT_CMPL ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_PlusCBST | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the +CBST AT command + which is responsible to set the bearer service parameters + for following mobile originated calls. + +*/ + +GLOBAL T_ACI_RETURN sAT_PlusCBST ( T_ACI_CMD_SRC srcId, + T_ACI_BS_SPEED speed, + T_ACI_CBST_NAM name, + T_ACI_CBST_CE ce) +{ + TRACE_FUNCTION ("sAT_PlusCBST()"); + + /* check command source */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + /* process the speed parameter */ + switch( speed ) + { + case( BS_SPEED_NotPresent ): + speed = ccShrdPrm.CBSTspeed; + break; + + case( BS_SPEED_AUTO ): + case( BS_SPEED_300_V21 ): + case( BS_SPEED_1200_V22 ): + case( BS_SPEED_1200_75_V23 ): + case( BS_SPEED_2400_V22bis ): + case( BS_SPEED_2400_V26ter ): + case( BS_SPEED_4800_V32 ): + case( BS_SPEED_9600_V32 ): + case( BS_SPEED_9600_V34 ): + case( BS_SPEED_14400_V34 ): +/* case( BS_SPEED_1200_V120 ): This layer 1 protocol is not supported + case( BS_SPEED_2400_V120 ): + case( BS_SPEED_4800_V120 ): + case( BS_SPEED_9600_V120 ): + case( BS_SPEED_14400_V120 ): */ + case( BS_SPEED_300_V110 ): + case( BS_SPEED_1200_V110 ): + case( BS_SPEED_2400_V110 ): + case( BS_SPEED_4800_V110 ): + case( BS_SPEED_9600_V110 ): + case( BS_SPEED_14400_V110 ): + break; + + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + /* process the name parameter */ + switch( name ) + { + case( CBST_NAM_NotPresent ): + name = ccShrdPrm.CBSTname; + break; + + case( CBST_NAM_Asynch ): + case( CBST_NAM_Synch ): + break; + + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + /* process the ce parameter */ + switch( ce ) + { + case( CBST_CE_NotPresent ): + ce = ccShrdPrm.CBSTce; + break; + + case( CBST_CE_Transparent ): + case( CBST_CE_NonTransparent ): + case( CBST_CE_BothTransPref ): + case( CBST_CE_BothNonTransPref ): + break; + + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + /* assign the parameters */ + ccShrdPrm.CBSTspeed = speed; + ccShrdPrm.CBSTname = name; + ccShrdPrm.CBSTce = ce; + + /* update CC setting for MTC */ + psaCC_Config(); + return( AT_CMPL ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_PlusCSTA | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the +CSTA AT command + which is responsible to set the type of address for further + dialing commands. + +*/ + +GLOBAL T_ACI_RETURN sAT_PlusCSTA ( T_ACI_CMD_SRC srcId, + T_ACI_TOA * toa ) +{ + T_CC_CMD_PRM * pCCCmdPrm; /* points to CC command parameters */ + + TRACE_FUNCTION ("sAT_PlusCSTA()"); + +/* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + +/* + *------------------------------------------------------------------- + * process the toa parameter + *------------------------------------------------------------------- + */ + if( ! toa ) return( AT_CMPL ); + + switch( toa -> ton ) + { + case( TON_Unknown ): + case( TON_International ): + case( TON_National ): + case( TON_NetSpecific ): + case( TON_DedAccess ): + break; + + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + switch( toa -> npi ) + { + case( NPI_Unknown ): + case( NPI_IsdnTelephony ): + case( NPI_Data ): + case( NPI_Telex ): + case( NPI_National ): + case( NPI_Private ): + break; + + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + pCCCmdPrm -> CSTAtoa.ton = toa -> ton; + pCCCmdPrm -> CSTAtoa.npi = toa -> npi; + pCCCmdPrm -> CSTAdef = FALSE; + + return( AT_CMPL ); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_DMY | +| STATE : code ROUTINE : sAT_PlusCTFR | ++--------------------------------------------------------------------+ + + PURPOSE : This refers to a service that causes an incoming alerting + call to be forwarded to a specified number. Action command + does this. + +*/ + +GLOBAL T_ACI_RETURN sAT_PlusCTFR ( T_ACI_CMD_SRC srcId, + CHAR *number, + T_ACI_TOA *type, + CHAR *subaddr, + T_ACI_TOS *satype) +{ + T_CC_CMD_PRM * pCCCmdPrm; /* points to CC command parameters */ +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + T_ACI_CLOG cmdLog; /* holds logging info */ +#endif /* #if defined SMI OR defined MFW OR defined FF_MMI_RIV */ + SHORT cId; /* holds call id */ + SHORT dscId; /* holds call disconnect id */ + UBYTE idx; /* holds index value */ + + TRACE_FUNCTION ("sAT_PlusCTFR()"); + + /* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + /* + * Check that number contains a valid dial string. + * A dial string is valid if it contains at least one valid dial + * character, garbage within the dial string is ignored (also spaces). + */ + if (strpbrk (number, "0123456789*#AaBbCc") EQ NULL) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + + /* + *------------------------------------------------------------------- + * prepare log command + *------------------------------------------------------------------- + */ +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.atCmd = AT_CMD_CTFR; + cmdLog.cmdType = CLOG_TYPE_Set; + cmdLog.retCode = AT_EXCT; + cmdLog.sId = ACI_NumParmNotPresent; + cmdLog.cId = NOT_PRESENT_8BIT; + cmdLog.cmdPrm.sCTFR.srcId = srcId; + cmdLog.cmdPrm.sCTFR.number = number; + cmdLog.cmdPrm.sCTFR.type = type; + cmdLog.cmdPrm.sCTFR.subaddr = subaddr; + cmdLog.cmdPrm.sCTFR.satype = satype; +#endif /* #if defined SMI OR defined MFW OR defined FF_MMI_RIV */ + + /* + *------------------------------------------------------------------- + * find the call for which Call Deflection shall be invoked + *------------------------------------------------------------------- + */ + dscId = -1; + + for (cId = 0; cId < MAX_CALL_NR; cId++) + { + if ((ccShrdPrm.ctb[cId] NEQ NULL) AND + (psaCC_ctb(cId)->calStat EQ CS_ACT_REQ) AND + (psaCC_ctb(cId)->calType EQ CT_MTC)) + { + dscId = cId; + break; + } + } + + if ((dscId >= 0) AND + (psaCC_ctb(dscId)->curCmd NEQ AT_CMD_NONE)) + { + return( AT_BUSY ); + } + + /* + * There is no check here whether CD is applicable for the specific + * telecommunication service (22.004 Normative Annex A), as CD is + * applicable for all CC telecommunication services. + * GSM 07.07 says CD was only applicable for teleservice 11, but this + * seems to be wrong. + */ + + /* + *------------------------------------------------------------------- + * Clear the incoming call with facility invoke component for CD + *------------------------------------------------------------------- + */ + /*lint -e{661} cId causes out of bounds access, it does not! */ + if( dscId >= 0 ) /* Implies cId also >= 0 */ + { + cmhCC_flagCall( dscId, &(pCCCmdPrm -> mltyDscFlg)); + psaCC_ctb(cId)->nrmCs = MNCC_CAUSE_CALL_CLEAR; + psaCC_ctb(cId)->curCmd = AT_CMD_CTFR; + psaCC_ctb(cId)->curSrc = srcId; + +#ifdef FF_ATI + io_setRngInd (IO_RING_OFF, CRING_TYP_NotPresent, CRING_TYP_NotPresent ); /* V.24 Ring Indicator Line */ +#endif + for (idx = 0; idx < CMD_SRC_MAX; idx++) + { + R_AT (RAT_CRING_OFF, idx)(dscId + 1); + } + + CCD_START; + { + psaCC_asmCDReq (number, type, subaddr, satype); + + psaCC_asmComponent (dscId); + + psaCC_ClearCall (dscId); + } + CCD_END; + + psaCC_ctb(cId)->CDStat = CD_Requested; + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = dscId + 1; + rAT_PercentCLOG( &cmdLog ); +#endif /* #if defined SMI OR defined MFW OR defined FF_MMI_RIV */ + + return( AT_EXCT ); + } + + /* + * No call with matching criteria has been found in the call table. + */ + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow ); + return AT_FAIL; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : find_waiting_held_call | ++--------------------------------------------------------------------+ + + PURPOSE : find waiting held calls + +*/ + +LOCAL T_ACI_RETURN find_waiting_held_call(SHORT *cwaId, + SHORT *hldId, + SHORT *rclId) +{ + SHORT cId; + + /* reinitialize */ + *cwaId = -1; + *hldId = -1; + *rclId = -1; + + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + if (ccShrdPrm.ctb[cId] NEQ NULL) + { + if( psaCC_ctb(cId)->calStat EQ CS_ACT_REQ AND + psaCC_ctb(cId)->calOwn EQ OWN_NONE AND + psaCC_ctb(cId)->calType EQ CT_MTC ) + { + *cwaId = cId; + } + + if( psaCC_ctb(cId)->calStat EQ CS_HLD ) + { + if(*hldId EQ -1) + { + /* take only first found call on hold (ex: in case of multiparty) */ + *hldId = cId; + } + } + + if( psaCC_ctb(cId)->calStat EQ CS_ACT_REQ AND + psaCC_ctb(cId)->calOwn EQ OWN_NONE AND + psaCC_ctb(cId)->calType EQ CT_NI_MOC ) + { + *rclId = cId; + } + } + } + + if((*cwaId >= 0 AND psaCC_ctb(*cwaId)->curCmd NEQ AT_CMD_NONE) OR + (*hldId >= 0 AND psaCC_ctb(*hldId)->curCmd NEQ AT_CMD_NONE) OR + (*rclId >= 0 AND psaCC_ctb(*rclId)->curCmd NEQ AT_CMD_NONE) ) + { + return( AT_BUSY ); + } + return(AT_CMPL); +} + +/* SEND LOG info to MFW */ +LOCAL void chld_ratlog( T_ACI_CMD_SRC srcId, + T_ACI_CHLD_MOD mode, + CHAR *call, + T_ACI_CHLD_ACT act, + SHORT cId, + T_ACI_RETURN acireturn ) +{ +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + T_ACI_CLOG cmdLog; /* holds logging info */ + + /* prepare log command */ + cmdLog.atCmd = AT_CMD_CHLD; + cmdLog.cmdType = CLOG_TYPE_Set; + cmdLog.sId = ACI_NumParmNotPresent; + cmdLog.cmdPrm.sCHLD.srcId = srcId; + cmdLog.cmdPrm.sCHLD.mode = mode; + cmdLog.cmdPrm.sCHLD.call = call; + + cmdLog.cmdPrm.sCHLD.act = act; + cmdLog.cId = cId+1; + cmdLog.retCode = acireturn; + + rAT_PercentCLOG( &cmdLog ); +#endif /* SMI OR defined MFW */ +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : chld_RelHldOrUdub | ++--------------------------------------------------------------------+ + + PURPOSE : ??? +*/ +LOCAL T_ACI_RETURN chld_RelHldOrUdub(T_ACI_CMD_SRC srcId) +{ + T_CC_CMD_PRM *pCCCmdPrm; /* points to CC command parameters */ + SHORT cId; + UBYTE idx; /* holds index value */ + SHORT dscId; /* holds call disconnect id */ + + TRACE_FUNCTION("chld_RelHldOrUdub"); + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + +/* + *--------------------------------------------------------------- + * clear a waiting call + *--------------------------------------------------------------- + */ + pCCCmdPrm -> mltyCncFlg = 0; + pCCCmdPrm -> mltyDscFlg = 0; + + cId = psaCC_ctbFindCall( OWN_NONE, CS_ACT_REQ, CT_MTC ); + + if( cId >= 0 ) + { + if( psaCC_ctb(cId)->curCmd NEQ AT_CMD_NONE ) + return( AT_BUSY ); + + pCCCmdPrm -> CHLDmode = CHLD_MOD_RelHldOrUdub; + CHLDaddInfo = NO_CHLD_ADD_INFO; + + cmhCC_ClearCall(cId, MNCC_CAUSE_USER_BUSY, srcId, AT_CMD_CHLD, NULL); + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm -> CHLDmode, NULL, CHLD_ACT_Release, cId, AT_EXCT ); + +#ifdef FF_ATI + io_setRngInd (IO_RING_OFF, CRING_TYP_NotPresent, CRING_TYP_NotPresent ); /* V.24 Ring Indicator Line */ +#endif + for( idx = 0; idx < CMD_SRC_MAX; idx++ ) + { + R_AT( RAT_CRING_OFF, idx )( cId+1 ); + } + + return( AT_EXCT ); + } + +/* + *--------------------------------------------------------------- + * clear a CCBS recall + *--------------------------------------------------------------- + */ + cId = psaCC_ctbFindCall( OWN_NONE, CS_ACT_REQ, CT_NI_MOC ); + + if( cId >= 0 ) + { + if( psaCC_ctb(cId)->curCmd NEQ AT_CMD_NONE ) + + return( AT_BUSY ); + + psaCC_ctb(cId)->nrmCs = MNCC_CAUSE_USER_BUSY; + + psaCC_ClearCall (cId); + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm -> CHLDmode, NULL, CHLD_ACT_Release, cId, AT_CMPL ); + + psaCC_FreeCtbNtry (cId); + return( AT_CMPL ); + } + +/* + *--------------------------------------------------------------- + * or clear all held calls + *--------------------------------------------------------------- + */ + dscId = -1; + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + if (ccShrdPrm.ctb[cId] NEQ NULL AND + psaCC_ctb(cId)->calStat EQ CS_HLD AND + psaCC_ctb(cId)->curCmd EQ AT_CMD_NONE) + { + cmhCC_ClearCall( cId, MNCC_CAUSE_CALL_CLEAR, srcId, AT_CMD_CHLD, NULL); + dscId = cId; + } + } + + if( ! pCCCmdPrm -> mltyDscFlg ) + { + return( AT_BUSY ); + } + else if (dscId >= 0) + { + pCCCmdPrm -> CHLDmode = CHLD_MOD_RelHldOrUdub; + CHLDaddInfo = NO_CHLD_ADD_INFO; + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, NULL, CHLD_ACT_Release, dscId, AT_EXCT ); + return( AT_EXCT ); + } + else + { + return( AT_FAIL ); + } +} + +/*----------------------------------------------------------------- + * release all active calls, and accept held or waiting call + *-----------------------------------------------------------------*/ +LOCAL T_ACI_RETURN chld_RelActAndAcpt(T_ACI_CMD_SRC srcId) +{ + SHORT cwaId; /* holds call waiting id */ + SHORT hldId; /* holds call hold id */ + SHORT rclId; /* holds recall id */ + SHORT dscId = -1; /* will be set if a call is disconnected (with its cId) */ + SHORT cId; + T_ACI_RETURN ret; + T_CC_CMD_PRM *pCCCmdPrm; /* points to CC command parameters */ + + TRACE_FUNCTION("chld_RelActAndAcpt"); + + /* find the waiting or held call */ + ret = find_waiting_held_call(&cwaId, &hldId, &rclId); + + TRACE_EVENT_P1("cwaId = %d", cwaId); + if(ret EQ AT_BUSY) + return(AT_BUSY); + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + +/* + *--------------------------------------------------------------- + * clear all active calls + *--------------------------------------------------------------- + */ + pCCCmdPrm -> mltyCncFlg = 0; + pCCCmdPrm -> mltyDscFlg = 0; + + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + if (ccShrdPrm.ctb[cId] NEQ NULL AND + psaCC_ctb(cId)->calStat EQ CS_ACT AND + psaCC_ctb(cId)->curCmd EQ AT_CMD_NONE) + { + psaCC_StopDTMF (cId); /* HM 27.07.00 */ + dscId = cId; + + cmhCC_ClearCall( cId, MNCC_CAUSE_CALL_CLEAR, srcId, AT_CMD_CHLD, NULL ); + } + } + +/* + *--------------------------------------------------------------- + * accept the waiting call + *--------------------------------------------------------------- + */ + if( cwaId >= 0 ) + { + cmhCC_flagCall( cwaId, &(pCCCmdPrm -> mltyCncFlg)); + pCCCmdPrm -> CHLDmode = CHLD_MOD_RelActAndAcpt; + + if( dscId NEQ -1 ) + { + CHLDaddInfo = CHLD_ADD_INFO_ACC_CAL; + } + else + { + cmhCC_AcceptCall(cwaId, srcId, AT_CMD_CHLD); + } + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, NULL, CHLD_ACT_Accept, cwaId, AT_EXCT ); + return( AT_EXCT ); + } + +/* + *--------------------------------------------------------------- + * accept the CCBS recall + *--------------------------------------------------------------- + */ + if( rclId >= 0 ) + { + cmhCC_flagCall( rclId, &(pCCCmdPrm -> mltyCncFlg)); + pCCCmdPrm -> CHLDmode = CHLD_MOD_RelActAndAcpt; + + /* + * The MSC in GSM 04.93, figure 4.3.2 says the SETUP for the CCBS + * call is sent immediately after the DISCONNECT for the existing + * call was sent into the network, they do not wait for a RELEASE + * from the network. This seems to be different for the call waiting + * case, compare this with the MSC in GSM 11.10 clause 31.3.1.2. + */ + cmhCC_NewCall(rclId, srcId, AT_CMD_D); + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, NULL, CHLD_ACT_Accept, rclId, AT_EXCT ); + return( AT_EXCT ); + } + +/* + *--------------------------------------------------------------- + * retrieve the held call + *--------------------------------------------------------------- + */ + if( hldId >= 0 ) + { + cmhCC_flagCall( hldId, &(pCCCmdPrm -> mltyCncFlg)); + pCCCmdPrm -> CHLDmode = CHLD_MOD_RelActAndAcpt; + + if( dscId NEQ -1 ) + { + CHLDaddInfo = CHLD_ADD_INFO_RTV_CAL; + } + else + { + cmhCC_RetrieveCall(hldId, srcId); + } + + /* inform MFW */ + chld_ratlog( srcId, + pCCCmdPrm->CHLDmode, + NULL, + (psaCC_ctb(hldId)->mptyStat EQ CS_ACT)? CHLD_ACT_RetrieveMpty:CHLD_ACT_Retrieve, + hldId, + AT_EXCT ); + + return( AT_EXCT ); + } + +/* + *--------------------------------------------------------------- + * at least one call was disconnected + *--------------------------------------------------------------- + */ + if( dscId NEQ -1 ) + { + pCCCmdPrm -> CHLDmode = CHLD_MOD_RelActAndAcpt; + CHLDaddInfo = NO_CHLD_ADD_INFO; + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, NULL, CHLD_ACT_Release, dscId, AT_EXCT ); + return( AT_EXCT ); + } + return (AT_FAIL); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : chld_RelActSpec | ++--------------------------------------------------------------------+ + + PURPOSE : release a specific active call +*/ +LOCAL T_ACI_RETURN chld_RelActSpec(T_ACI_CMD_SRC srcId, CHAR *call) +{ + T_CC_CMD_PRM *pCCCmdPrm; /* points to CC command parameters */ + SHORT spcId; /* holds specified call id */ + SHORT dscId = -1; /* will be set if a call is disconnected (with its cId) */ + SHORT cId; /* holds call id */ + + TRACE_FUNCTION("chld_RelActSpec"); + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + + /* get specific call id */ + if( call EQ NULL ) + { + TRACE_ERROR("CALL parameter is needed !!!"); + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); /* no call specified */ + } + + spcId = atoi( call ); + + if( spcId EQ 0 OR spcId > MAX_CALL_NR ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + spcId--; /* adapt to call table index */ + + pCCCmdPrm -> mltyCncFlg = 0; + pCCCmdPrm -> mltyDscFlg = 0; + +/* + *--------------------------------------------------------------- + * clear specific multiparty call + *--------------------------------------------------------------- + */ + if( spcId EQ -1 ) + { + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + if (ccShrdPrm.ctb[cId] NEQ NULL AND + psaCC_ctb(cId)->mptyStat EQ CS_ACT AND + psaCC_ctb(cId)->curCmd EQ AT_CMD_NONE) + { + psaCC_StopDTMF (cId); + + cmhCC_ClearCall ( cId, MNCC_CAUSE_CALL_CLEAR, srcId, AT_CMD_CHLD, NULL ); + dscId = cId; + } + } + + if( dscId NEQ -1 ) + { + pCCCmdPrm -> CHLDmode = CHLD_MOD_RelActSpec; + CHLDaddInfo = NO_CHLD_ADD_INFO; + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, call, CHLD_ACT_ReleaseMpty, dscId, AT_EXCT ); + return( AT_EXCT ); + } + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow ); + return(AT_FAIL); + } + +/* + *--------------------------------------------------------------- + * clear the specific active call if possible + *--------------------------------------------------------------- + */ + if (ccShrdPrm.ctb[spcId] EQ NULL OR psaCC_ctb(spcId)->calStat NEQ CS_ACT) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow ); + return( AT_FAIL ); /* specific call does not match condition */ + } + + cmhCC_ClearCall ( spcId, MNCC_CAUSE_CALL_CLEAR, srcId, AT_CMD_CHLD, NULL ); + + pCCCmdPrm -> CHLDmode = CHLD_MOD_RelActSpec; + CHLDaddInfo = NO_CHLD_ADD_INFO; + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, call, CHLD_ACT_Release, spcId, AT_EXCT ); + return( AT_EXCT ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : chld_RelAnySpec | ++--------------------------------------------------------------------+ + + PURPOSE : release a specific call +*/ +LOCAL T_ACI_RETURN chld_RelAnySpec(T_ACI_CMD_SRC srcId, CHAR *call) +{ + T_CC_CMD_PRM *pCCCmdPrm; /* points to CC command parameters */ + SHORT spcId; /* holds specified call id */ + SHORT dscId = -1; /* will be set if a call is disconnected (with its cId) */ + SHORT cId; /* holds call id */ + SHORT waitId = NO_ENTRY; /* holds call waiting id */ + UBYTE idx = 0; /* temporary counter */ + + TRACE_FUNCTION("chld_RelAnySpec"); + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + + /* get specific call id */ + if( call EQ NULL ) + { + TRACE_ERROR("CALL parameter is needed !!!"); + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); /* no call specified */ + } + + spcId = atoi( call ); + + if( spcId EQ 0 OR spcId > MAX_CALL_NR ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + spcId--; /* adapt to call table index */ + + pCCCmdPrm -> mltyCncFlg = 0; + pCCCmdPrm -> mltyDscFlg = 0; + +/* + *--------------------------------------------------------------- + * clear specific multiparty call + *--------------------------------------------------------------- + */ + if( spcId EQ -1 ) + { + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + if (ccShrdPrm.ctb[cId] NEQ NULL AND + psaCC_ctb(cId)->mptyStat EQ CS_ACT AND + psaCC_ctb(cId)->curCmd EQ AT_CMD_NONE) + { + psaCC_StopDTMF (cId); + + cmhCC_ClearCall ( cId, MNCC_CAUSE_CALL_CLEAR, srcId, AT_CMD_CHLD, NULL ); + dscId = cId; + } + } + + if( dscId NEQ -1 ) + { + pCCCmdPrm -> CHLDmode = CHLD_MOD_RelAnySpec; + CHLDaddInfo = NO_CHLD_ADD_INFO; + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, call, CHLD_ACT_ReleaseMpty, dscId, AT_EXCT ); + return( AT_EXCT ); + } + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow ); + return(AT_FAIL); + } + +/* + *--------------------------------------------------------------- + * clear the specific call if possible + *--------------------------------------------------------------- + */ + if (ccShrdPrm.ctb[spcId] EQ NULL) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow ); + return( AT_FAIL ); /* specific call does not match condition */ + } + + cmhCC_ClearCall ( spcId, MNCC_CAUSE_CALL_CLEAR, srcId, AT_CMD_CHLD, &waitId ); + + /* The call that shall be released is a waiting call (stop ringing) */ + if( waitId NEQ NO_ENTRY ) + { + cmhCC_flagCall( waitId, &(pCCCmdPrm -> mltyDscFlg)); + psaCC_ctb(waitId)->nrmCs = MNCC_CAUSE_USER_BUSY; + psaCC_ctb(waitId)->curCmd = AT_CMD_CHLD; + psaCC_ctb(waitId)->curSrc = srcId; + psaCC_ClearCall (waitId); + +#ifdef AT_INTERPRETER + io_setRngInd (IO_RING_OFF, CRING_TYP_NotPresent, CRING_TYP_NotPresent ); /* V.24 Ring Indicator Line */ +#endif + for( idx = 0; idx < CMD_SRC_MAX; idx++ ) + { + R_AT( RAT_CRING_OFF, idx )( waitId+1 ); + } + } + + pCCCmdPrm->CHLDmode = CHLD_MOD_RelAnySpec; + CHLDaddInfo = NO_CHLD_ADD_INFO; + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, call, CHLD_ACT_Release, spcId, AT_EXCT ); + return( AT_EXCT ); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : chld_HldActAndAcpt | ++--------------------------------------------------------------------+ + + PURPOSE : place all active calls on hold, and accept held or waiting + call +*/ +LOCAL T_ACI_RETURN chld_HldActAndAcpt(T_ACI_CMD_SRC srcId) +{ + T_CC_CMD_PRM *pCCCmdPrm; /* points to CC command parameters */ + SHORT cId; /* holds call id */ + T_ACI_RETURN ret; + SHORT cwaId; /* holds call waiting id */ + SHORT hldId; /* holds call hold id */ + SHORT rclId; /* holds recall id */ + BOOL hldCalFlg = FALSE; /* flags a held call */ + BOOL mptyHldFlg = FALSE; /* flags a multiparty held call */ + T_ACI_CHLD_ACT chldact; /* contains the type of CHLD activity when informing MFW */ + TRACE_FUNCTION("chld_HldActAndAcpt"); + + /* find the waiting or held call */ + ret = find_waiting_held_call(&cwaId, &hldId, &rclId); + + if(ret EQ AT_BUSY) + return(AT_BUSY); + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + + if( cwaId >=0 AND hldId >=0 ) + { + /* check for Active Call if already Held Call and Waiting Call */ + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + if (ccShrdPrm.ctb[cId] NEQ NULL AND + psaCC_ctb(cId)->calStat EQ CS_ACT AND + psaCC_ctb(cId)->curCmd EQ AT_CMD_NONE ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_OneCallOnHold ); + return( AT_FAIL ); /* only one call could be on hold, + no chance for the waiting call */ + } + } + } + +/* + *--------------------------------------------------------------- + * put all active calls on hold + *--------------------------------------------------------------- + */ + pCCCmdPrm -> mltyCncFlg = 0; + pCCCmdPrm -> mltyDscFlg = 0; + + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + if (ccShrdPrm.ctb[cId] NEQ NULL AND + psaCC_ctb(cId)->calStat EQ CS_ACT AND + psaCC_ctb(cId)->curCmd EQ AT_CMD_NONE) + { + if( cmhCC_getcalltype(cId) NEQ VOICE_CALL ) + { + pCCCmdPrm -> mltyCncFlg = 0; + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_CallTypeNoHold ); + return( AT_FAIL ); /* no data calls supported */ + } + + if( psaCC_ctb(cId)->mptyStat EQ CS_IDL OR + (psaCC_ctb(cId)->mptyStat EQ CS_ACT AND + mptyHldFlg EQ FALSE )) + { + hldCalFlg = TRUE; + } + + /* if active call is a multiparty call */ + if( psaCC_ctb(cId)->mptyStat EQ CS_ACT ) + { + mptyHldFlg = TRUE; + } + + cmhCC_HoldCall(cId, srcId, AT_CMD_CHLD); + } + } + +/* + *--------------------------------------------------------------- + * accept the waiting call + *--------------------------------------------------------------- + */ + if( cwaId >= 0 ) + { + cmhCC_flagCall( cwaId, &(pCCCmdPrm -> mltyCncFlg)); + pCCCmdPrm -> CHLDmode = CHLD_MOD_HldActAndAcpt; + + if( hldCalFlg ) + { + CHLDaddInfo = CHLD_ADD_INFO_ACC_CAL; + } + else + { + cmhCC_AcceptCall(cwaId, srcId, AT_CMD_CHLD); + } + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, NULL, CHLD_ACT_Accept, cwaId, AT_EXCT ); + return( AT_EXCT ); + } + +/* + *--------------------------------------------------------------- + * accept the CCBS recall + *--------------------------------------------------------------- + */ + if( rclId >= 0 ) + { + cmhCC_flagCall( rclId, &(pCCCmdPrm -> mltyCncFlg)); + pCCCmdPrm -> CHLDmode = CHLD_MOD_HldActAndAcpt; + + if( hldCalFlg ) + { + CHLDaddInfo = CHLD_ADD_INFO_DIAL_CAL; + } + else + { + cmhCC_NewCall(rclId, srcId, AT_CMD_CHLD); + } + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, NULL, CHLD_ACT_Accept, rclId, AT_EXCT ); + return( AT_EXCT ); + } + +/* + *--------------------------------------------------------------- + * retrieve the held call + *--------------------------------------------------------------- + */ + if( hldId >= 0 ) + { + cmhCC_flagCall( hldId, &(pCCCmdPrm -> mltyCncFlg)); + pCCCmdPrm -> CHLDmode = CHLD_MOD_HldActAndAcpt; + + cmhCC_RetrieveCall(hldId, srcId); + + /* inform MFW */ + if( hldCalFlg ) + { + chldact = (mptyHldFlg)? CHLD_ACT_SwapMpty:CHLD_ACT_Swap; + } + else + { + chldact = (psaCC_ctb(hldId)->mptyStat EQ CS_ACT)? CHLD_ACT_RetrieveMpty :CHLD_ACT_Retrieve; + } + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, NULL, chldact, hldId, AT_EXCT ); + return( AT_EXCT ); + } + +/* + *--------------------------------------------------------------- + * at least one call was put on hold + *--------------------------------------------------------------- + */ + if( hldCalFlg ) + { + pCCCmdPrm -> CHLDmode = CHLD_MOD_HldActAndAcpt; + CHLDaddInfo = NO_CHLD_ADD_INFO; + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, + NULL, + (mptyHldFlg)? CHLD_ACT_HoldMpty:CHLD_ACT_Hold, + cId, AT_EXCT ); + return( AT_EXCT ); + } + return( AT_FAIL ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : chld_HldActExc | ++--------------------------------------------------------------------+ + + PURPOSE : put all active calls on hold except the specified call +*/ +LOCAL T_ACI_RETURN chld_HldActExc(T_ACI_CMD_SRC srcId, CHAR *call) +{ + T_CC_CMD_PRM *pCCCmdPrm; /* points to CC command parameters */ + SHORT spcId; /* holds specified call id */ + SHORT cId; /* holds call id */ + BOOL hldCalFlg = FALSE; /* flags a held call */ + BOOL mptyHldFlg = FALSE; /* flags a multiparty held call */ + T_ACI_CHLD_ACT chld_act; + + TRACE_FUNCTION("chld_HldActExc"); + + if( call EQ NULL ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); /* no call specified */ + } + + spcId = atoi( call ); + + if( spcId EQ 0 OR spcId > MAX_CALL_NR ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + spcId--; /* adapt to call table index */ + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + + pCCCmdPrm -> mltyCncFlg = 0; + pCCCmdPrm -> mltyDscFlg = 0; + + /* + *------------------------------------------------------------- + * if specified call is active and no multiparty + *------------------------------------------------------------- + */ + /* no action needed */ + + /* + *------------------------------------------------------------- + * if specified call is active and member of multiparty + *------------------------------------------------------------- + */ + if (ccShrdPrm.ctb[spcId] NEQ NULL AND + psaCC_ctb(spcId)->calStat EQ CS_ACT AND + psaCC_ctb(spcId)->mptyStat EQ CS_ACT AND + psaCC_ctb(spcId)->curCmd EQ AT_CMD_NONE) + { + /* If this is a multiparty with only one call left then we must not split! */ + if (psaCC_CountMPTY() > 1) + { + cmhCC_flagCall( spcId, &(pCCCmdPrm -> mltyCncFlg)); + + psaCC_ctb(spcId)->curCmd = AT_CMD_CHLD; + psaCC_ctb(spcId)->curSrc = srcId; + + psaCC_SplitMPTY(spcId); + + chld_act = CHLD_ACT_SplitMpty; + } + else + { + /* call is already active, so command has no effect */ + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Unknown ); + return( AT_FAIL ); + } + } + + /* + *------------------------------------------------------------- + * if specified call is on hold and no multiparty + *------------------------------------------------------------- + */ + else if (ccShrdPrm.ctb[spcId] NEQ NULL AND + psaCC_ctb(spcId)->calStat EQ CS_HLD AND + psaCC_ctb(spcId)->mptyStat EQ CS_IDL AND + psaCC_ctb(spcId)->curCmd EQ AT_CMD_NONE) + { + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + if (ccShrdPrm.ctb[cId] NEQ NULL AND + psaCC_ctb(cId)->calStat EQ CS_ACT AND + psaCC_ctb(cId)->curCmd EQ AT_CMD_NONE) + { + if( cmhCC_getcalltype(cId) NEQ VOICE_CALL ) + { + pCCCmdPrm -> mltyCncFlg = 0; + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_CallTypeNoHold ); + return( AT_FAIL ); /* no data calls supported */ + } + + hldCalFlg = TRUE; + if( psaCC_ctb(cId)->mptyStat EQ CS_ACT ) + { + mptyHldFlg = TRUE; + } + cmhCC_HoldCall(cId, srcId, AT_CMD_CHLD); + } + } + + cmhCC_flagCall( spcId, &(pCCCmdPrm -> mltyCncFlg)); + pCCCmdPrm -> CHLDmode = CHLD_MOD_HldActExc; + + cmhCC_RetrieveCall(spcId, srcId); + + if( hldCalFlg ) + { + chld_act = (mptyHldFlg)? + CHLD_ACT_SwapMpty:CHLD_ACT_Swap; + } + else + chld_act = (mptyHldFlg)? + CHLD_ACT_RetrieveMpty:CHLD_ACT_Retrieve; + } + + /* + *------------------------------------------------------------- + * if specified call is on hold and member of multiparty + *------------------------------------------------------------- + */ + else if (ccShrdPrm.ctb[spcId] NEQ NULL AND + psaCC_ctb(spcId)->calStat EQ CS_HLD AND + psaCC_ctb(spcId)->mptyStat EQ CS_ACT AND + psaCC_ctb(spcId)->curCmd EQ AT_CMD_NONE) + { + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + if (ccShrdPrm.ctb[cId] NEQ NULL AND + psaCC_ctb(cId)->calStat EQ CS_ACT AND + psaCC_ctb(cId)->curCmd EQ AT_CMD_NONE) + { + if( cmhCC_getcalltype(cId) NEQ VOICE_CALL ) + { + pCCCmdPrm -> mltyCncFlg = 0; + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_CallTypeNoHold ); + return( AT_FAIL ); /* no data calls supported */ + } + + hldCalFlg = TRUE; + + cmhCC_HoldCall(cId, srcId, AT_CMD_CHLD); + } + } + + cmhCC_flagCall( spcId, &(pCCCmdPrm -> mltyCncFlg)); + pCCCmdPrm -> CHLDmode = CHLD_MOD_HldActExc; + + CHLDaddInfo = NO_CHLD_ADD_INFO; + + psaCC_ctb(spcId)->curCmd = AT_CMD_CHLD; + psaCC_ctb(spcId)->curSrc = srcId; + + /* If this is a multiparty with only one call left then we must not split! */ + if (psaCC_CountMPTY() > 1) + { + psaCC_SplitMPTY(spcId); + chld_act = CHLD_ACT_SplitMpty; + } + else + { + cmhCC_RetrieveCall(spcId, srcId); + chld_act = CHLD_ACT_Retrieve; + } + } + + /* + *------------------------------------------------------------- + * if other command is running on specified call + *------------------------------------------------------------- + */ + else if (ccShrdPrm.ctb[spcId] NEQ NULL AND + psaCC_ctb(spcId)->curCmd NEQ AT_CMD_NONE) + { + return( AT_BUSY ); + } + + /* + *------------------------------------------------------------- + * unknown condition + *------------------------------------------------------------- + */ + else + { + TRACE_ERROR ("Unknown condition"); + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Unknown ); + return( AT_FAIL ); + } + + + /* + *------------------------------------------------------------- + * send return code + *------------------------------------------------------------- + */ + if( pCCCmdPrm -> mltyCncFlg NEQ 0 ) + { + pCCCmdPrm -> CHLDmode = CHLD_MOD_HldActExc; + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, call, chld_act, spcId, AT_EXCT ); + return( AT_EXCT ); + } + else + { + return( AT_CMPL ); + } +} + +/*----------------------------------------------------------------- + * add a held call to the conversation + *-----------------------------------------------------------------*/ +LOCAL T_ACI_RETURN chld_AddHld(T_ACI_CMD_SRC srcId) +{ + SHORT actId; /* holds call active id */ + T_CC_CMD_PRM *pCCCmdPrm; /* points to CC command parameters */ + + TRACE_FUNCTION("chld_AddHld( )"); + + /* search a held call */ + if( psaCC_ctbFindCall( NO_VLD_OWN, CS_HLD, NO_VLD_CT ) EQ NO_ENTRY ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow ); + return( AT_FAIL ); + } + + actId = psaCC_ctbFindCall( NO_VLD_OWN, CS_ACT, NO_VLD_CT ); + + if( actId EQ NO_ENTRY ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow ); + return( AT_FAIL ); + } + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + + cmhCC_flagCall( actId, &(pCCCmdPrm -> mltyCncFlg)); + + psaCC_ctb(actId)->curCmd = AT_CMD_CHLD; + psaCC_ctb(actId)->curSrc = srcId; + + psaCC_BuildMPTY(actId); + + pCCCmdPrm -> CHLDmode = CHLD_MOD_AddHld; + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, NULL, CHLD_ACT_BuildMpty, actId, AT_EXCT ); + return( AT_EXCT ); +} + +/*----------------------------------------------------------------- + * explicit call transfer + *-----------------------------------------------------------------*/ +LOCAL T_ACI_RETURN chld_Ect(T_ACI_CMD_SRC srcId) +{ + SHORT cId; /* holds call id */ + SHORT actId; /* holds call active id */ + SHORT hldId; /* holds call hold id */ + T_CC_CMD_PRM * pCCCmdPrm; /* points to CC command parameters */ + + TRACE_FUNCTION("chld_Ect"); +/* + *--------------------------------------------------------------- + * find the active(req) or held call + *--------------------------------------------------------------- + */ + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + + actId = hldId = -1; + + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + if (ccShrdPrm.ctb[cId] NEQ NULL) + { + if( cmhCC_getcalltype(cId) NEQ VOICE_CALL ) + { + /* not a valid id for ECT */ + } + else if (psaCC_ctb(cId)->calStat EQ CS_ACT OR + (psaCC_ctb(cId)->calStat EQ CS_ACT_REQ AND + psaCC_ctb(cId)->calType EQ CT_MOC)) + { + if( actId EQ -1 ) actId = cId; + } + else if( psaCC_ctb(cId)->calStat EQ CS_HLD ) + { + if( hldId EQ -1 ) hldId = cId; + } + } + } + + /* + * if command state is not idle + */ + if(actId >= 0) + { + switch(psaCC_ctb(actId)->curCmd) + { + case(AT_CMD_NONE): + case(AT_CMD_D): + /* command state where actId might find itself */ + break; + default: + TRACE_EVENT_P1("CHLD ECT: actId busy with %d", psaCC_ctb(actId)->curCmd); + return( AT_BUSY ); + } + } + + + if( hldId >= 0 AND + psaCC_ctb(hldId)->curCmd NEQ AT_CMD_NONE ) + { + TRACE_EVENT_P1("CHLD ECT: hldId busy with %d", psaCC_ctb(hldId)->curCmd); + return( AT_BUSY ); + } + + if( actId >= 0 AND hldId >= 0 ) + { + cmhCC_flagCall( actId, &(pCCCmdPrm -> mltyDscFlg)); + cmhCC_flagCall( hldId, &(pCCCmdPrm -> mltyDscFlg)); + psaCC_ctb(actId)->curCmd = AT_CMD_CHLD; + psaCC_ctb(actId)->curSrc = srcId; + psaCC_ctb(hldId)->curCmd = AT_CMD_CHLD; + psaCC_ctb(hldId)->curSrc = srcId; + ccShrdPrm.cIdMPTY = actId; + + if( psaCC_ECT(hldId) NEQ 0 ) + { + return(AT_FAIL); + } + + pCCCmdPrm -> CHLDmode = CHLD_MOD_Ect; + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, NULL, CHLD_ACT_ECT, actId, AT_EXCT ); + return( AT_EXCT ); + } + + TRACE_EVENT("CHLD: ECT: could not find interesting call ids"); + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow ); + return( AT_FAIL ); +} + +/*----------------------------------------------------------------- + * activate call completion to busy subscriber + *-----------------------------------------------------------------*/ +LOCAL T_ACI_RETURN chld_Ccbs(T_ACI_CMD_SRC srcId) +{ + T_CC_CMD_PRM *pCCCmdPrm; /* points to CC command parameters */ + SHORT dscId = -1; /* will be set if a call is disconnected (with its cId) */ + SHORT cId; /* holds call id */ + + TRACE_FUNCTION("chld_Ccbs"); + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + +/* + *--------------------------------------------------------------- + * find the call with CCBS possible + *--------------------------------------------------------------- + */ + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + if (ccShrdPrm.ctb[cId] NEQ NULL AND + psaCC_ctb(cId)->calStat EQ CS_DSC_REQ AND + psaCC_ctb(cId)->calType EQ CT_MOC AND + psaCC_ctb(cId)->CCBSstat EQ CCBSS_PSSBL) + { + dscId = cId; + break; + } + } + + if( dscId >= 0 AND + psaCC_ctb(dscId)->curCmd NEQ AT_CMD_NONE ) + + return( AT_BUSY ); + +/* + *--------------------------------------------------------------- + * clear a call with CCBS possible + *--------------------------------------------------------------- + */ + /*lint -e{661} cId causes out of bounds access, it does not! */ + if( dscId >= 0 ) + { + pCCCmdPrm -> CHLDmode = CHLD_MOD_Ccbs; + CHLDaddInfo = NO_CHLD_ADD_INFO; + psaCC_ctb(cId)->CCBSstat = CCBSS_REQ; + + cmhCC_ClearCall ( dscId, MNCC_CAUSE_CALL_CLEAR, srcId, AT_CMD_CHLD, NULL ); + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, NULL, CHLD_ACT_CCBS, dscId, AT_EXCT ); + return( AT_EXCT ); + } + + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow ); + return( AT_FAIL ); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : chld_OnlyHold | ++--------------------------------------------------------------------+ + + PURPOSE : Put a call on hold (and nothing else ==> do not accept + any other call) +*/ +LOCAL T_ACI_RETURN chld_OnlyHold(T_ACI_CMD_SRC srcId) +{ + SHORT hldId; /* holds call hold id */ + SHORT cId; /* holds call id */ + T_CC_CMD_PRM *pCCCmdPrm; /* points to CC command parameters */ + BOOL hldCalFlg = FALSE; /* flags a held call */ + BOOL mptyHldFlg = FALSE; /* flags a multiparty held call */ + + TRACE_FUNCTION("chld_OnlyHold"); + + /* find held call */ + hldId = -1; + + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + if (ccShrdPrm.ctb[cId] NEQ NULL) + { + if( psaCC_ctb(cId)->calStat EQ CS_HLD ) + { + if( hldId EQ -1 ) hldId = cId; + } + } + } + + if( hldId >=0 ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_OneCallOnHold ); + return( AT_FAIL ); /* only one call could be on hold */ + } + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + + /* put all active calls on hold */ + pCCCmdPrm -> mltyCncFlg = 0; + pCCCmdPrm -> mltyDscFlg = 0; + + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + if (ccShrdPrm.ctb[cId] NEQ NULL AND + psaCC_ctb(cId)->calStat EQ CS_ACT AND + psaCC_ctb(cId)->curCmd EQ AT_CMD_NONE ) + { + if( cmhCC_getcalltype(cId) NEQ VOICE_CALL ) + { + pCCCmdPrm -> mltyCncFlg = 0; + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_CallTypeNoHold ); + return( AT_FAIL ); /* no data calls supported */ + } + + if( psaCC_ctb(cId)->mptyStat EQ CS_IDL OR + (psaCC_ctb(cId)->mptyStat EQ CS_ACT AND + mptyHldFlg EQ FALSE )) + { + hldCalFlg = TRUE; + } + + /* if active call is a multiparty call */ + if( psaCC_ctb(cId)->mptyStat EQ CS_ACT ) + { + mptyHldFlg = TRUE; + } + cmhCC_HoldCall(cId, srcId, AT_CMD_CHLD); + } + } + + /* at least one call was put on hold */ + if( hldCalFlg ) + { + pCCCmdPrm -> CHLDmode = CHLD_MOD_OnlyHold; + CHLDaddInfo = NO_CHLD_ADD_INFO; + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, + NULL, + (mptyHldFlg)? CHLD_ACT_HoldMpty:CHLD_ACT_Hold, + cId, AT_EXCT ); + return( AT_EXCT ); + } + return( AT_FAIL ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : chld_RelDialCall | ++--------------------------------------------------------------------+ + + PURPOSE : release diealling call (special function for FAE's +*/ +LOCAL T_ACI_RETURN chld_RelDialCall(T_ACI_CMD_SRC srcId) +{ + T_CC_CMD_PRM *pCCCmdPrm; /* points to CC command parameters */ + SHORT cId; + + TRACE_FUNCTION("chld_RelDialCall"); + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + +/* + *--------------------------------------------------------------- + * clear the dialling call + *--------------------------------------------------------------- + */ + pCCCmdPrm -> mltyCncFlg = 0; + pCCCmdPrm -> mltyDscFlg = 0; + + cId = psaCC_ctbFindCall( srcId, CS_ACT_REQ, CT_MOC ); + + TRACE_EVENT_P1("Call Id of dialling call = %d",cId); + + if( cId >= 0 ) + { + pCCCmdPrm -> CHLDmode = CHLD_MOD_RelDialCall; + CHLDaddInfo = NO_CHLD_ADD_INFO; + + cmhCC_ClearCall(cId, MNCC_CAUSE_CALL_CLEAR, srcId, AT_CMD_CHLD, NULL); + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm -> CHLDmode, NULL, CHLD_ACT_Release, cId, AT_EXCT ); + + return( AT_EXCT ); + } + + /* Unable to find call */ + return( AT_FAIL); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : chld_RetrieveHoldCall | ++--------------------------------------------------------------------+ + + PURPOSE : retrieve an held call (and nothing else) + - waiting call's still knocked on + - will hold active call +*/ +LOCAL T_ACI_RETURN chld_RetrieveHoldCall(T_ACI_CMD_SRC srcId) +{ + T_CC_CMD_PRM *pCCCmdPrm; /* points to CC command parameters */ + SHORT cId; /* call id */ + SHORT cwaId = -1; /* holds call waiting id */ + SHORT hldId = -1; /* holds call hold id */ + SHORT rclId = -1; /* holds recall id */ + BOOL mptyHldFlg = FALSE; /* flags a multiparty held call */ + BOOL hldCalFlg = FALSE; /* flags a held call */ + T_ACI_CHLD_ACT chldact; /* contains the type of CHLD activity when informing MFW */ + + TRACE_FUNCTION("chld_RetrieveHoldCall"); + + /* find the waiting or held call */ + if( find_waiting_held_call(&cwaId, &hldId, &rclId) EQ AT_BUSY) + { + return(AT_BUSY); + } + + if( hldId < 0 ) + { /* no held call found */ + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_CallNotFound ); + return( AT_FAIL ); + } + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; /* temp copy */ + +/* + *--------------------------------------------------------------- + * put all active calls on hold + *--------------------------------------------------------------- + */ + pCCCmdPrm -> mltyCncFlg = 0; + pCCCmdPrm -> mltyDscFlg = 0; + + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + if (ccShrdPrm.ctb[cId] NEQ NULL AND + psaCC_ctb(cId)->calStat EQ CS_ACT AND + psaCC_ctb(cId)->curCmd EQ AT_CMD_NONE) + { + if( cmhCC_getcalltype(cId) NEQ VOICE_CALL ) + { + pCCCmdPrm -> mltyCncFlg = 0; + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_CallTypeNoHold ); + return( AT_FAIL ); /* no data calls supported */ + } + + if( (psaCC_ctb(cId)->mptyStat EQ CS_IDL) OR + ((psaCC_ctb(cId)->mptyStat EQ CS_ACT) AND (mptyHldFlg EQ FALSE)) ) + { + hldCalFlg = TRUE; + } + + /* if active call is a multiparty call */ + if( psaCC_ctb(cId)->mptyStat EQ CS_ACT ) + { + mptyHldFlg = TRUE; + } + + cmhCC_HoldCall(cId, srcId, AT_CMD_CHLD); + } + } + + /* maybe, one or more calls were put on hold */ + if( hldCalFlg ) + { + pCCCmdPrm -> CHLDmode = CHLD_MOD_HldActAndAcpt; + CHLDaddInfo = NO_CHLD_ADD_INFO; + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, + NULL, + (mptyHldFlg)? CHLD_ACT_HoldMpty:CHLD_ACT_Hold, + cId, AT_EXCT ); + } + +/* + *--------------------------------------------------------------- + * retrieve the held call + *--------------------------------------------------------------- + */ + cmhCC_flagCall(hldId, &(pCCCmdPrm -> mltyCncFlg)); + pCCCmdPrm -> CHLDmode = CHLD_MOD_RetrieveHoldCall; + + cmhCC_RetrieveCall(hldId, srcId); + + /* inform MFW */ + chldact = (psaCC_ctb(hldId)->mptyStat EQ CS_ACT)? CHLD_ACT_RetrieveMpty :CHLD_ACT_Retrieve; + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, NULL, chldact, hldId, AT_EXCT ); + return( AT_EXCT ); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : chld_RetrieveHoldCallSpec| ++--------------------------------------------------------------------+ + + PURPOSE : retrieve specific held call (and nothing else) + - release waiting call + - will hold active call +*/ +LOCAL T_ACI_RETURN chld_RetrieveHoldCallSpec(T_ACI_CMD_SRC srcId, CHAR *call) +{ + T_CC_CMD_PRM *pCCCmdPrm; /* points to CC command parameters */ + SHORT cId; /* call id */ + SHORT temp_cId; + SHORT cwaId = -1; /* holds call waiting id */ + SHORT hldId = -1; /* holds call hold id */ + SHORT rclId = -1; /* holds recall id */ + BOOL mptyHldFlg = FALSE; /* flags a multiparty held call */ + BOOL hldCalFlg = FALSE; /* flags a held call */ + T_ACI_CHLD_ACT chldact; /* contains the type of CHLD activity when informing MFW */ + + TRACE_FUNCTION("chld_RetrieveHoldCallSpec"); + + if( call EQ NULL ) + { + TRACE_ERROR("CALL parameter is needed !!!"); + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); /* no call specified */ + } + + cId = atoi( call ); /* char --> int */ + + if( (cId EQ 0) OR (cId > MAX_CALL_NR) ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + cId--; /* adapt to call table index */ + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + + /* test whether specified call is a held call */ + if ((ccShrdPrm.ctb[cId] EQ NULL) OR + (psaCC_ctb(cId)->calStat NEQ CS_HLD) OR + (psaCC_ctb(cId)->curCmd NEQ AT_CMD_NONE) OR + (cmhCC_getcalltype(cId) NEQ VOICE_CALL)) + { /* no held call or no voice call --> error */ + pCCCmdPrm -> mltyCncFlg = 0; + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_CallTypeNoHold ); + return( AT_FAIL ); /* no data calls supported */ + } + + +/* + *--------------------------------------------------------------- + * put all active calls on hold + *--------------------------------------------------------------- + */ + pCCCmdPrm -> mltyCncFlg = 0; + pCCCmdPrm -> mltyDscFlg = 0; + + for( temp_cId = 0; temp_cId < MAX_CALL_NR; temp_cId++ ) + { + T_CC_CALL_TBL *pCallTable = ccShrdPrm.ctb[temp_cId]; + + if( pCallTable NEQ NULL AND + pCallTable->calStat EQ CS_ACT AND + pCallTable->curCmd EQ AT_CMD_NONE ) + { + if( cmhCC_getcalltype(temp_cId) NEQ VOICE_CALL ) + { + pCCCmdPrm -> mltyCncFlg = 0; + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_CallTypeNoHold ); + return( AT_FAIL ); /* no data calls supported */ + } + + if( (pCallTable->mptyStat EQ CS_IDL) OR + ((pCallTable->mptyStat EQ CS_ACT) AND (mptyHldFlg EQ FALSE)) ) + { + hldCalFlg = TRUE; + } + + /* if active call is a multiparty call */ + if( pCallTable->mptyStat EQ CS_ACT ) + { + mptyHldFlg = TRUE; + } + + cmhCC_HoldCall(temp_cId, srcId, AT_CMD_CHLD); + } + } + + /* maybe, one or more calls were put on hold */ + if( hldCalFlg ) + { + pCCCmdPrm->CHLDmode = CHLD_MOD_HldActAndAcpt; + CHLDaddInfo = NO_CHLD_ADD_INFO; + + /* inform MFW */ + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, + NULL, + (mptyHldFlg)? CHLD_ACT_HoldMpty:CHLD_ACT_Hold, + cId, AT_EXCT ); + } + +/* + *--------------------------------------------------------------- + * retrieve the held call + *--------------------------------------------------------------- + */ + cmhCC_flagCall(cId, &(pCCCmdPrm -> mltyCncFlg)); + pCCCmdPrm -> CHLDmode = CHLD_MOD_RetrieveHoldCallSpec; + + cmhCC_RetrieveCall(cId, srcId); + + /* inform MFW */ + if (psaCC_ctb(cId)->mptyStat EQ CS_ACT) + chldact = CHLD_ACT_RetrieveMpty; + else + chldact = CHLD_ACT_Retrieve; + chld_ratlog( srcId, pCCCmdPrm->CHLDmode, NULL, chldact, cId, AT_EXCT ); + return( AT_EXCT ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_PlusCHLD | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the +CHLD AT command + which is responsible to handle the supplementary services + witin a call +*/ +GLOBAL T_ACI_RETURN sAT_PlusCHLD ( T_ACI_CMD_SRC srcId, + T_ACI_CHLD_MOD mode, + CHAR *call) +{ + TRACE_FUNCTION ("sAT_PlusCHLD()"); + + if( mode > CHLD_MOD_RelDialCall ) + { /* not allowed modes inside '+'-command */ + TRACE_EVENT("this mode is not allowed for sAT_PlusCHLD()"); + return( AT_FAIL ); + } + else + { + return( cmhCC_CHLD_Serv(srcId, mode, call) ); + } +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_PercentCHLD | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the %CHLD AT command + which is responsible to handle the supplementary services + witin a call +*/ +GLOBAL T_ACI_RETURN sAT_PercentCHLD ( T_ACI_CMD_SRC srcId, + T_ACI_CHLD_MOD mode, + CHAR *call) +{ + TRACE_FUNCTION ("sAT_PercentCHLD()"); + + return( cmhCC_CHLD_Serv(srcId, mode, call) ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_PlusCCUG | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the +CCUG AT command + which is responsible to set the parameters for closed user + group supplementary services. + + <mode> : CUG mode. + <index> : CUG index. + <info> : CUG info. +*/ + +GLOBAL T_ACI_RETURN sAT_PlusCCUG ( T_ACI_CMD_SRC srcId, + T_ACI_CCUG_MOD mode, + T_ACI_CCUG_IDX index, + T_ACI_CCUG_INFO info) +{ + T_CC_CMD_PRM * pCCCmdPrm; /* points to CC command parameters */ + + TRACE_FUNCTION ("sAT_PlusCCUG()"); + +/* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + +/* + *------------------------------------------------------------------- + * process the mode parameter + *------------------------------------------------------------------- + */ + switch( mode ) + { + case( CCUG_MOD_NotPresent ): + + mode = pCCCmdPrm -> CCUGmode; + break; + + case( CCUG_MOD_DisableTmp ): + case( CCUG_MOD_EnableTmp ): + + break; + + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + +/* + *------------------------------------------------------------------- + * process the index parameter + *------------------------------------------------------------------- + */ + switch( index ) + { + case( CCUG_IDX_NotPresent ): + + index = pCCCmdPrm -> CCUGidx; + break; + + case( CCUG_IDX_0 ): + case( CCUG_IDX_1 ): + case( CCUG_IDX_2 ): + case( CCUG_IDX_3 ): + case( CCUG_IDX_4 ): + case( CCUG_IDX_5 ): + case( CCUG_IDX_6 ): + case( CCUG_IDX_7 ): + case( CCUG_IDX_8 ): + case( CCUG_IDX_9 ): + case( CCUG_IDX_No ): + + break; + + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + +/* + *------------------------------------------------------------------- + * process the info parameter + *------------------------------------------------------------------- + */ + switch( info ) + { + case( CCUG_INFO_NotPresent ): + + info = pCCCmdPrm -> CCUGinfo; + break; + + case( CCUG_INFO_No ): + case( CCUG_INFO_SuppOa ): + case( CCUG_INFO_SuppPrefCug ): + case( CCUG_INFO_SuppBoth ): + + break; + + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + +/* + *------------------------------------------------------------------- + * assign the parameters + *------------------------------------------------------------------- + */ + pCCCmdPrm -> CCUGmode = mode; + pCCCmdPrm -> CCUGidx = index; + pCCCmdPrm -> CCUGinfo = info; + + return( AT_CMPL ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_PlusVTS | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the +VTS AT command + which is responsible to send DTMF tones. +*/ + +GLOBAL T_ACI_RETURN sAT_PlusVTS ( T_ACI_CMD_SRC srcId, + CHAR dtmf, + T_ACI_VTS_MOD mode ) +{ + SHORT cId; /* holds call id */ + T_CC_CMD_PRM *pCCCmdPrm; /* points to CC command parameters */ + BOOL param_ok; + + TRACE_FUNCTION ("sAT_PlusVTS()"); + +/* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + + cId = cmhCC_find_call_for_DTMF( ); + if (cId EQ NO_ENTRY) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow ); + return( AT_FAIL ); + } + + /* allow to send DTMF tone one after another quickly + if( psaCC_ctb(cId)->dtmfCmd NEQ AT_CMD_NONE ) + return( AT_BUSY );*/ + + /* if DTMF are already being sent */ + if (( ccShrdPrm.dtmf.cnt AND mode NEQ VTS_MOD_ManStop ) OR + ( ccShrdPrm.dtmf.cur AND (mode NEQ VTS_MOD_ManStop))) + { + TRACE_EVENT("DTMF are already being sent !"); + return( AT_BUSY ); + } + else if ( !ccShrdPrm.dtmf.cur AND mode EQ VTS_MOD_ManStop ) + { + TRACE_EVENT("Cannot stop a DTMF tone that hasn't been started!"); + return( AT_FAIL ); + } + else if ( ccShrdPrm.dtmf.cur AND (ccShrdPrm.dtmf.cur NEQ dtmf )) + { + TRACE_EVENT("Cannot stop a different DTMF tone than the one that is started!"); + return( AT_FAIL ); + } + + /* process mode parameter */ + switch( mode ) + { + case( VTS_MOD_Auto ): + psaCC_ctb(cId)->dtmfMode = DTMF_MOD_AUTO; + break; + + case( VTS_MOD_ManStart ): + psaCC_ctb(cId)->dtmfMode = DTMF_MOD_MAN_START; + ccShrdPrm.dtmf.cur = dtmf; + break; + + case( VTS_MOD_ManStop ): + psaCC_ctb(cId)->dtmfMode = DTMF_MOD_MAN_STOP; + break; + + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow ); + return( AT_FAIL ); + } + + psaCC_ctb(cId)->dtmfCmd = AT_CMD_VTS; /* wait for confirmation */ + psaCC_ctb(cId)->dtmfSrc = srcId; + /* has to remember tone sent in case of an abort */ + ccShrdPrm.dtmf.cnt = 1; + ccShrdPrm.dtmf.dig[0] = dtmf; + ccShrdPrm.dtmf.cId = cId; + + param_ok = cmhCC_SendDTMFdig ( AT_CMD_VTS, cId, dtmf, psaCC_ctb(cId)->dtmfMode); + + if( param_ok ) + { + return( AT_EXCT ); + } + else + { + ccShrdPrm.dtmf.cnt = 0; + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_PlusCSNS | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the +CSNS AT command + which is responsible to set the parameters for single + numbering scheme. +*/ + +GLOBAL T_ACI_RETURN sAT_PlusCSNS ( T_ACI_CMD_SRC srcId, + T_ACI_CSNS_MOD mode) +{ + T_CC_CMD_PRM *pCCCmdPrm; /* points to CC command parameters */ + + TRACE_FUNCTION ("sAT_PlusCSNS()"); + +/* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + +/* + *------------------------------------------------------------------- + * check parameter mode + *------------------------------------------------------------------- + */ + switch( mode ) + { + case( CSNS_MOD_NotPresent ): + + mode = CSNS_MOD_Voice; + break; + + case( CSNS_MOD_Voice ): + case( CSNS_MOD_VAFVoice ): + case( CSNS_MOD_Fax ): + case( CSNS_MOD_VADVoice ): + case( CSNS_MOD_Data ): + case( CSNS_MOD_VAFFax ): + case( CSNS_MOD_VADData ): + case( CSNS_MOD_VFD ): + + break; + + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + ccShrdPrm.snsMode = mode; + + psaCC_Config( ); + + return( AT_CMPL ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_AndF | ++--------------------------------------------------------------------+ + + PURPOSE : Reset all values to defaults. +*/ + +GLOBAL T_ACI_RETURN sAT_AndF ( T_ACI_CMD_SRC srcId, + SHORT value) +{ + + TRACE_FUNCTION ("sAT_AndF()"); + +/* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + +/* + *------------------------------------------------------------------- + * check parameter value + *------------------------------------------------------------------- + */ + if( value NEQ 0 AND value NEQ ACI_NumParmNotPresent ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + +/* + *------------------------------------------------------------------- + * reset value to defaults + *------------------------------------------------------------------- + */ + cmh_Reset ( srcId, TRUE ); + + return( AT_CMPL ); +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sGsmAT_Z | ++--------------------------------------------------------------------+ + + PURPOSE : Reset all values to factory defaults in the GSM part of ACI. +*/ + +GLOBAL T_ACI_RETURN sGsmAT_Z ( T_ACI_CMD_SRC srcId ) +{ + SHORT cId; /* holds call id */ + SHORT waitId = NO_ENTRY; /* holds call waiting id */ + T_CC_CMD_PRM * pCCCmdPrm; /* points to CC command parameters */ + UBYTE idx; + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + T_ACI_CLOG cmdLog; /* holds logging info */ +#endif + + TRACE_FUNCTION ("sGsmAT_Z()"); + +/* + *------------------------------------------------------------------- + * command source is checked + *------------------------------------------------------------------- + */ + pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm; + +/* + *------------------------------------------------------------------- + * prepare log command + *------------------------------------------------------------------- + */ +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.atCmd = AT_CMD_Z; + cmdLog.cmdType = CLOG_TYPE_Set; + cmdLog.retCode = AT_EXCT; + cmdLog.sId = ACI_NumParmNotPresent; + cmdLog.cmdPrm.sH.srcId = srcId; +#endif /* End of SMI Or defined MFW*/ + +/* + *------------------------------------------------------------------- + * clear all calls except a waiting call + *------------------------------------------------------------------- + */ + pCCCmdPrm -> mltyDscFlg = 0; + + for( cId = 0; cId < MAX_CALL_NR; cId++ ) + { + /* Clear only calls in use ! */ + if (ccShrdPrm.ctb[cId] NEQ NULL) + { + cmhCC_ClearCall(cId,MNCC_CAUSE_CALL_CLEAR, srcId, AT_CMD_Z, &waitId); + } + } + + if( pCCCmdPrm -> mltyDscFlg ) + { +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = cId+1; + rAT_PercentCLOG( &cmdLog ); +#endif + return( AT_EXCT ); + } + +/* + *------------------------------------------------------------------- + * disconnect a waiting call with user determined user busy + *------------------------------------------------------------------- + */ + if( waitId NEQ NO_ENTRY ) + { + cmhCC_flagCall( waitId, &(pCCCmdPrm -> mltyDscFlg)); + psaCC_ctb(waitId)->nrmCs = MNCC_CAUSE_USER_BUSY; + psaCC_ctb(waitId)->curCmd = AT_CMD_Z; + psaCC_ctb(waitId)->curSrc = srcId; + psaCC_ClearCall (waitId); + +#if defined SMI OR defined MFW OR defined FF_MMI_RIV + cmdLog.cId = waitId+1; + rAT_PercentCLOG( &cmdLog ); +#endif + +#ifdef FF_ATI + io_setRngInd ( IO_RING_OFF, CRING_TYP_NotPresent, CRING_TYP_NotPresent ); /* V.24 Ring Indicator Line */ +#endif + for( idx = 0; idx < CMD_SRC_MAX; idx++ ) + { + R_AT( RAT_CRING_OFF, idx )( waitId+1 ); + } + return( AT_EXCT ); + } + +/* + *------------------------------------------------------------------- + * reset value to default if no call is active + *------------------------------------------------------------------- + */ + cmh_Reset ( srcId, TRUE ); + + R_AT(RAT_Z, srcId)(); + + return( AT_CMPL ); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_Z | ++--------------------------------------------------------------------+ + + PURPOSE : Reset all values to factory defaults. +*/ + +GLOBAL T_ACI_RETURN sAT_Z ( T_ACI_CMD_SRC srcId, + SHORT value) +{ + + TRACE_FUNCTION ("sAT_Z()"); + +/* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + +/* + *------------------------------------------------------------------- + * check parameter value + *------------------------------------------------------------------- + */ + if( value NEQ 0 AND value NEQ ACI_NumParmNotPresent ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + +/* + *------------------------------------------------------------------- + * clear all calls and reset all value to default + *------------------------------------------------------------------- + */ + +#if defined (GPRS) AND defined (DTI) + return sGprsAT_Z ( srcId ); +#else + return sGsmAT_Z ( srcId ); +#endif /* GPRS */ +} + +#if defined (FAX_AND_DATA) AND defined (DTI) +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_O | ++--------------------------------------------------------------------+ + + PURPOSE : Return to online mode +*/ + +GLOBAL T_ACI_RETURN sAT_O ( T_ACI_CMD_SRC srcId ) +{ + SHORT cId; /* holds call id */ + T_DTI_CONN_CB *dti_conn_cb; + T_DTI_ENTITY_ID entity_list[2]; +#ifdef FF_PSI + T_ACI_DTI_PRC_PSI *src_infos_psi = NULL; +#endif /* FF_PSI */ + TRACE_FUNCTION("sAT_O()"); + +/* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + +/* + *------------------------------------------------------------------- + * find active call + *------------------------------------------------------------------- + */ + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_ACT, NO_VLD_CT ); + + if( cId EQ NO_ENTRY ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_CallNotFound ); + return( AT_FAIL ); + } + + switch( cmhCC_getcalltype(cId) ) + { + case( TRANS_CALL ): + entity_list[0] = DTI_ENTITY_TRA; + dti_conn_cb = TRA_connect_dti_cb; + break; + + case( NON_TRANS_CALL ): + entity_list[0] = DTI_ENTITY_L2R; + dti_conn_cb = L2R_connect_dti_cb; + break; + + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow ); + return( AT_FAIL ); + } + + if( psaCC_ctb(cId)->curCmd NEQ AT_CMD_NONE ) + return( AT_BUSY ); + + R_AT( RAT_CONNECT, srcId ) + ( AT_CMD_O, cmhCC_GetDataRate(&psaCC_ctb(cId)-> + BC[psaCC_ctb(cId)->curBC]), + cId+1, FALSE ); + + psaCC_ctb(cId)->curCmd = AT_CMD_O; + psaCC_ctb(cId)->curSrc = srcId; + + + if (IS_SRC_BT(srcId)) + { + entity_list[1] = DTI_ENTITY_BLUETOOTH; + dti_cntrl_est_dpath((UBYTE)srcId, entity_list, 2, SPLIT, dti_conn_cb); + } + else + { +#ifdef FF_PSI + src_infos_psi = find_element(psi_src_params,(UBYTE) srcId, cmhPSItest_srcId); + memset(&psi_ato,0,sizeof(T_ACI_PSI_CALL_TYPE)); + if (src_infos_psi NEQ NULL) + { + psi_ato.src_id = (UBYTE)srcId; + psi_ato.entity_to_conn = entity_list[0]; + psi_ato.num_entities = 1; + psi_ato.mode = SPLIT; + psi_ato.cb = dti_conn_cb; + psi_ato.capability = DTI_CPBLTY_SER; + psi_ato.cid = DTI_CID_NOTPRESENT; + psi_ato.last_cmd = AT_CMD_O; + } + else + { +#endif /* FF_PSI */ + dti_cntrl_est_dpath_indirect ( (UBYTE)srcId, + entity_list, + 1, + SPLIT, + dti_conn_cb, + DTI_CPBLTY_SER, + DTI_CID_NOTPRESENT); +#ifdef FF_PSI + } +#endif /* FF_PSI */ + } + + return( AT_EXCT ); +} +#endif + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| ROUTINE : sAT_PercentALS | ++-------------------------------------------------------------------+ + + PURPOSE : set the ALS mode for outgoing calls (voice) + ALS_MOD_SPEECH: + indicates bearer capability => BEARER_SERV_SPEECH + ALS_MOD_AUX_SPEECH: + indicates bearer capability => BEARER_SERV_AUX_SPEECH +*/ + +GLOBAL T_ACI_RETURN sAT_PercentALS( T_ACI_CMD_SRC srcId, + T_ACI_ALS_MOD mode ) +{ + TRACE_FUNCTION("sAT_PercentALS()"); + + if( !cmh_IsVldCmdSrc( srcId ) ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + /* line will really change? */ + if (mode EQ cmhPrm[srcId].ccCmdPrm.ALSmode) + { + return (AT_CMPL); + } + + if ( ALSlock NEQ ALS_MOD_NOTPRESENT ) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow ); + return( AT_FAIL ); + } + + if ( mode EQ ALS_MOD_SPEECH ) + { + cmhPrm[srcId].ccCmdPrm.ALSmode = ALS_MOD_SPEECH; + return( AT_CMPL ); + } + else if ( mode EQ ALS_MOD_AUX_SPEECH ) + { + /* E-Plus SIM-Card inserted (mcc=0x262, mnc=0x03) ? */ + if (cmhSIM_plmn_is_hplmn(0x262, 0x03F)) + { + cmhPrm[srcId].ccCmdPrm.ALSmode = ALS_MOD_AUX_SPEECH; + return( AT_CMPL ); + } + else + { + simEntStat.curCmd = AT_CMD_ALS; + simEntStat.entOwn = simShrdPrm.owner = srcId; + + ccShrdPrm.als_cmd = ALS_CMD_SET; + + cmhCC_checkALS_Support(); + return (AT_EXCT); + } + } + else + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } +} + +/* ++-------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| ROUTINE : sAT_PercentCTTY | ++-------------------------------------------------------------------+ + + PURPOSE : Handling TTY +*/ + +GLOBAL T_ACI_RETURN sAT_PercentCTTY (T_ACI_CMD_SRC srcId, + T_ACI_CTTY_MOD mode, + T_ACI_CTTY_REQ req) +{ + +#ifdef FF_TTY + SHORT cId; /* holds call id */ + T_TTY_CMD ttyAction = TTY_OFF; + T_bcpara *bc; + + TRACE_FUNCTION("sAT_PercentCTTY()"); + + if (!cmh_IsVldCmdSrc( srcId )) + { + ACI_ERR_DESC (ACI_ERR_CLASS_Ext, EXT_ERR_Parameter); + return AT_FAIL; + } + + /* + * find if any call is active + */ + cId = psaCC_ctbFindCall( NO_VLD_OWN, CS_ACT, NO_VLD_CT); + + if(cId NEQ NO_ENTRY ) + { + T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId]; + + TRACE_EVENT ("sAT_PercentCTTY() Active call found "); + + /* + * if command state is not idle + */ + switch(ctb->curCmd) + { + case(AT_CMD_NONE): + break; + default: + TRACE_EVENT_P1("CTTY: cId busy with %d", ctb->curCmd); + return( AT_BUSY ); + } + + /* + * Check if the active call is a TTY call + */ + bc = &ctb->BC[ctb->curBC]; + + if (bc->bearer_serv EQ BEARER_SERV_SPEECH_CTM OR + bc->bearer_serv EQ BEARER_SERV_AUX_SPEECH_CTM) + { + if ((mode EQ CTTY_MOD_Disable) OR (mode EQ CTTY_MOD_Enable)) + { + cmhPrm[srcId].ccCmdPrm.CTTYmode = mode; + } + + switch (req) + { + case CTTY_REQ_Off: + /* + * stop the running TTY, a normal voice call + */ + ccShrdPrm.ctmReq = CTM_DISABLED; + ccShrdPrm.ttyCmd = (UBYTE)TTY_OFF; + + cmhCC_TTY_Control (cId, TTY_STOP); + return( AT_CMPL ); + + case CTTY_REQ_On: + ccShrdPrm.ctmReq = CTM_ENABLED; + ccShrdPrm.ttyCmd = (UBYTE)TTY_ALL; + break; + case CTTY_REQ_HCO: + ccShrdPrm.ctmReq = CTM_ENABLED; + ccShrdPrm.ttyCmd = (UBYTE)TTY_HCO; + break; + case CTTY_REQ_VCO: + ccShrdPrm.ctmReq = CTM_ENABLED; + ccShrdPrm.ttyCmd = (UBYTE)TTY_VCO; + break; + default: + ACI_ERR_DESC (ACI_ERR_CLASS_Ext, EXT_ERR_Parameter); + return AT_FAIL; + } + + audio_dyn_set_tty (ttyAction = (T_TTY_CMD)ccShrdPrm.ttyCmd); + + /* + * This is for the case when mode is changed from Voice to any other + */ + ccShrdPrm.ctmState = TTY_STATE_ACTIVE; + + cmhCC_notifyTTY (CTTY_NEG_Grant, cmhCC_getTTYtrx_state (ttyAction)); + + return AT_CMPL; + } + else + { + /* + * If the active call is a normal GSM call then its a wrong bearer cap + */ + TRACE_EVENT_P1 ("TTY wrong BCAP: %d", (int)bc->bearer_serv); + return (AT_FAIL); + } + } + else + { + /* + * If no active call then its a static switching set the bearer cap + * for next and subsequent calls + */ + TRACE_EVENT ("sAT_PercentCTTY() No active call found "); + + if ((mode EQ CTTY_MOD_Disable) OR (mode EQ CTTY_MOD_Enable)) + { + cmhPrm[srcId].ccCmdPrm.CTTYmode = mode; + } + switch (req) + { + case CTTY_REQ_Off: + ccShrdPrm.ctmReq = CTM_DISABLED; + ccShrdPrm.ttyCmd = (UBYTE)TTY_OFF; + psaCC_Config (); + break; + case CTTY_REQ_On: + ccShrdPrm.ctmReq = CTM_ENABLED; + ccShrdPrm.ttyCmd = (UBYTE)TTY_ALL; + psaCC_Config (); + break; + case CTTY_REQ_HCO: + ccShrdPrm.ctmReq = CTM_ENABLED; + ccShrdPrm.ttyCmd = (UBYTE)TTY_HCO; + psaCC_Config (); + break; + case CTTY_REQ_VCO: + ccShrdPrm.ctmReq = CTM_ENABLED; + ccShrdPrm.ttyCmd = (UBYTE)TTY_VCO; + psaCC_Config (); + break; + default: + ACI_ERR_DESC (ACI_ERR_CLASS_Ext, EXT_ERR_Parameter); + return AT_FAIL; + } + if (req EQ CTTY_REQ_Off) + { + if (ccShrdPrm.ctmState EQ TTY_STATE_IDLE) + { + ccShrdPrm.ctmState = TTY_STATE_NONE; + } + } + else + { + if (ccShrdPrm.ctmState EQ TTY_STATE_NONE) + { + ccShrdPrm.ctmState = TTY_STATE_IDLE; + } + } + return AT_CMPL; + } +#else + ACI_ERR_DESC (ACI_ERR_CLASS_Cme, CME_ERR_OpNotSupp); + return AT_FAIL; +#endif /* FF_TTY */ +} + +#ifdef DTI +#if defined (FF_WAP) || defined (FF_GPF_TCPIP) || defined (FF_SAT_E) +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_PercentWAP | ++--------------------------------------------------------------------+ + + PURPOSE : set next call as a WAP call / unsent WAP call +*/ + +GLOBAL T_ACI_RETURN sAT_PercentWAP ( T_ACI_CMD_SRC srcId , SHORT setflag ) +{ + TRACE_FUNCTION("sAT_PercentWAP()"); + + switch (setflag) + { + case (0): /* unsent WAP call */ + /* End of processing of WAP entities */ + /* WAP-dedicated variables shall be reinitialized */ + wapId = NO_ENTRY; + Wap_Call = FALSE; + wap_state = Wap_Not_Init; + if ( wap_dti_id NEQ DTI_DTI_ID_NOTPRESENT ) + { + dti_cntrl_erase_entry (wap_dti_id); + wap_dti_id = DTI_DTI_ID_NOTPRESENT; + } + break; + + case (1): /* next call will be a WAP call */ + if (!Wap_Call) + { + Wap_Call = TRUE; +#ifdef FF_TCP_IP + /* FST: not possible in the moment -> see #ifdef before function definition */ + + /* reset is_PPP_CALL */ + pppShrdPrm.is_PPP_CALL = FALSE; +#endif + } + else + { + TRACE_EVENT("ERROR: a WAP Call is currently in progress"); + return AT_FAIL; + } + break; + } + + return AT_CMPL; +} +#endif /* of WAP || FF_GPF_TCPIP || SAT E */ +#endif /* DTI */ + +#ifdef MFW +/* MMI TEST AT COMMAND */ + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_PercentMMITEST | ++--------------------------------------------------------------------+ + + PURPOSE : This command has been introduced in order to use the AT command interface for some MMI + specific testing. It shoudnt be compiled without MMI. + +*/ + + +GLOBAL T_ACI_RETURN sAT_PercentMMITEST(T_ACI_CMD_SRC srcId, char *param) +{ + + TRACE_FUNCTION ("sAT_PercentMMITEST ()"); + +/* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + rAT_PercentMMITEST(param); + + return AT_CMPL; +} /* sAT_PercentMMITEST */ + +#endif + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : rdlPrm_init | ++--------------------------------------------------------------------+ + + PURPOSE : initializing of redial parameter +*/ +GLOBAL void rdlPrm_init(void) +{ + TRACE_FUNCTION ("rdlPrm_init ()"); + + rdlPrm.rdlBlN = NO_NOTIF_USER; + rdlPrm.rdlcId = NO_ENTRY; + rdlPrm.rdlMod = AUTOM_REPEAT_OFF; + rdlPrm.rdlModN = NO_NOTIF_USER; + rdlPrm.rdlBlMod = BLMODE_NO_PRESENT; + + +#if defined(_TARGET_) + cmhCC_rd_mode_FFS(AUTOM_REP_NOT_PRESENT,READ_RDLmode); /* read redial mode from FFS */ + if(rdlPrm.rdlMod EQ AUTOM_REPEAT_ON) + { + if(cc_blacklist_ptr EQ NULL) + { + ACI_MALLOC(cc_blacklist_ptr,sizeof(T_ACI_CC_REDIAL_BLACKL)); + memset(cc_blacklist_ptr, 0 , sizeof(T_ACI_CC_REDIAL_BLACKL)); + } + } +#endif /* _TARGET_ */ +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : rdlPrm_exit | ++--------------------------------------------------------------------+ + + PURPOSE : +*/ +GLOBAL void rdlPrm_exit(void) +{ + TRACE_FUNCTION ("rdlPrm_exit ()"); + + rdlPrm.rdlBlN = NO_NOTIF_USER; + rdlPrm.rdlcId = NO_ENTRY; + rdlPrm.rdlMod = AUTOM_REP_NOT_PRESENT; + rdlPrm.rdlModN = NO_NOTIF_USER; + rdlPrm.rdlBlMod = BLMODE_NO_PRESENT; + + if(cc_blacklist_ptr NEQ NULL) + { + ACI_MFREE(cc_blacklist_ptr); + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_PercentRDL | ++--------------------------------------------------------------------+ + + PURPOSE : This command has been introduced in order to set the + redial mode and notification state referring to outgoing + calls on ON/OFF +*/ +GLOBAL T_ACI_RETURN sAT_PercentRDL(T_ACI_CMD_SRC srcId, + T_ACI_CC_REDIAL_MODE redial_mode, + T_ACI_CC_REDIAL_NOTIF notification) +{ + int i; + + TRACE_FUNCTION ("sAT_PercentRDL ()"); + +/* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + if(redial_mode EQ AUTOM_REP_NOT_PRESENT) + { + redial_mode = rdlPrm.rdlMod; + } + + switch(notification) + { + case NOTIF_NO_PRESENT: + notification = rdlPrm.rdlModN; + break; + case NOTIF_USER: + case NO_NOTIF_USER: + rdlPrm.rdlModN = notification; + break; + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + switch(redial_mode) + { + case AUTOM_REPEAT_OFF: +#if defined(_TARGET_) + /* store redial mode in FFS */ + cmhCC_rd_mode_FFS(redial_mode,WRITE_RDLmode); +#endif /* _TARGET_ */ + /* stop redialling timer if necessary */ + if (rdlPrm.rdlcId NEQ NO_ENTRY) + { + TIMERSTOP(ACI_REPEAT_HND); + if(rdlPrm.rdlcId NEQ -1) + {/* clear call id entry in call table if marked as used */ + psaCC_FreeCtbNtry (rdlPrm.rdlcId); + for(i = 0; i < CMD_SRC_MAX; i++) + { + R_AT(RAT_RDL, i)(REDIAL_STOP); + } + } + } + /* reset redial parameter */ + rdlPrm_init(); + return AT_CMPL; + case AUTOM_REPEAT_ON: + rdlPrm.rdlMod = redial_mode; +#if defined(_TARGET_) + /* store redial mode in FFS */ + cmhCC_rd_mode_FFS(redial_mode,WRITE_RDLmode); +#endif /* _TARGET_ */ + /* allocate blacklist for phone numbers forbidden to call */ + if(cc_blacklist_ptr EQ NULL) + { + /* Check if we have enough RAM for the following ACI_MALLOC */ + USHORT free, alloc; + int ret; + ret = vsi_m_status ( hCommACI, + sizeof(T_ACI_CC_REDIAL_BLACKL), + PRIM_POOL_PARTITION, + &free, + &alloc ); + if (ret EQ VSI_ERROR || free EQ 0) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_MemFull); + return (AT_FAIL); + } + ACI_MALLOC(cc_blacklist_ptr,sizeof(T_ACI_CC_REDIAL_BLACKL)); + memset(cc_blacklist_ptr, 0 , sizeof(T_ACI_CC_REDIAL_BLACKL)); + } + return AT_CMPL; + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCS | +| STATE : code ROUTINE : sAT_PercentRDLB | ++--------------------------------------------------------------------+ + + PURPOSE : This command has been introduced in order to delete the + black list entries (forbidden outgoing phone numbers) +*/ +GLOBAL T_ACI_RETURN sAT_PercentRDLB(T_ACI_CMD_SRC srcId, + T_ACI_CC_REDIAL_BLMODE blacklist_mode, + T_ACI_CC_REDIAL_NOTIF notification) +{ + TRACE_FUNCTION ("sAT_PercentRDLB ()"); + +/* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + if(rdlPrm.rdlMod EQ AUTOM_REPEAT_ON) + { + + switch(blacklist_mode) + { + case BLMODE_NO_PRESENT: + rdlPrm.rdlBlMod = BL_NO_DELETE; /* if no parameter is given the black list is not deleted */ + break; + case BL_NO_DELETE: + case BL_DELETE: + /* store black list mode */ + rdlPrm.rdlBlMod = blacklist_mode; + break; + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + /* store black list notification mode */ + switch(notification) + { + case NOTIF_NO_PRESENT: + notification = rdlPrm.rdlBlN; + break; + case NOTIF_USER: + case NO_NOTIF_USER: + rdlPrm.rdlBlN = notification; + break; + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + /* reset black list entries */ + if(rdlPrm.rdlBlMod EQ BL_DELETE) + { + cc_blacklist_ptr->blCount = 0; + } + return AT_CMPL; + } + else + {/* redial mode switched OFF */ + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : CMH_CCQ | +| STATE : code ROUTINE : sAT_PercentCUSCFG | ++--------------------------------------------------------------------+ + + PURPOSE : This is the functional counterpart to the AT%CUSCFG set command + which sets the customization state of the facility specified. + +*/ +GLOBAL T_ACI_RETURN sAT_PercentCUSCFG(T_ACI_CMD_SRC srcId, + T_ACI_CUSCFG_FAC facility, + T_ACI_CUSCFG_MOD mode, + CHAR * value) +{ + TRACE_FUNCTION ("sAT_PercentCUSCFG ()"); + + /* + *------------------------------------------------------------------- + * check command source + *------------------------------------------------------------------- + */ + if(!cmh_IsVldCmdSrc (srcId)) + { + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + + switch(facility) + { + case CUSCFG_FAC_MO_SM_Control: + cuscfgParams.MO_SM_Control_SIM = mode; + break; + + case CUSCFG_FAC_MO_Call_Control: + cuscfgParams.MO_Call_Control_SIM = mode; + break; + + case CUSCFG_FAC_MO_SS_Control: + cuscfgParams.MO_SS_Control_SIM = mode; + break; + + case CUSCFG_FAC_MO_USSD_Control: + cuscfgParams.MO_USSD_Control_SIM = mode; + break; + + case CUSCFG_FAC_2_Digit_Call: + cuscfgParams.Two_digit_MO_Call = mode; + break; + + case CUSCFG_FAC_Ext_USSD_Res: + cuscfgParams.Ext_USSD_Response = mode; + break; + + default: + ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter ); + return( AT_FAIL ); + } + return(AT_CMPL); +} + +/*==== EOF ========================================================*/