line source
/*
+-----------------------------------------------------------------------------
| 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 ========================================================*/