FreeCalypso > hg > fc-magnetite
view src/aci2/aci/cmh_ccs.c @ 581:a0a45c5eb3ef
gsmcomp.c: bumping trace partition size to 220 like in gprscomp.c
This change is safe in terms of RAM usage because all of these partition
pools have already been moved from XRAM to IRAM earlier, and our IRAM
usage in VO configs is currently quite low - the one near the limit
is XRAM on C11x.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 29 Jan 2019 03:52:49 +0000 |
parents | 93999a60b835 |
children |
line wrap: on
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 ========================================================*/