/* 
+----------------------------------------------------------------------------- 
|  Project :  GSM-F&D (8411)
|  Modul   :  ACI_BAT
+-----------------------------------------------------------------------------
|  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 BAT callback  modul is ...
| 
+----------------------------------------------------------------------------- 
*/ 
 
#include "aci_all.h"     /* includes prim.h, which includes p_bat.h */

#define  ACI_BAT_CB_GLOBALS /* define this file as owner of globals in aci_bat_cb.h */
#include "aci_bat_cb.h" /* prototypes of sBAT_,qBAT_,tBAT_ */ 

#include "psa_psi.h"
#include "p_bat.h"
#include "aci_bat_err.h"
#include "aci_bat.h"
#include "aci_cmh.h"
#include "psa.h"
#include "cmh.h"
#include "aci_lst.h"
#include "cmh_psi.h"
#include "ati_cmd.h"
#include "aci_cmd.h"
#include "aci_fd.h"
#include "cmh_sms.h"


/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : aci_bat_src_info     |
+--------------------------------------------------------------------+

  PURPOSE : Can be called from rBAT_ functions in order to find the
            command source ID and a pointer to the PSI source
            information.
*/
LOCAL void aci_bat_src_info (T_ACI_CMD_SRC *src_id, T_ACI_DTI_PRC_PSI **psi_src_info)
{
  /*
  *   The source ID is copied from the global variable srcId_cb, 
  *   which is set by the macro R_AT.
  */
  *src_id=(T_ACI_CMD_SRC)srcId_cb;

  /*
  *   Use the function 'find_element()' to search for the PSI
  *   source that has the correct command source ID.
  */
  *psi_src_info=find_element(psi_src_params,srcId_cb,cmhPSItest_srcId);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : aci_bat_lang_str     |
+--------------------------------------------------------------------+

  PURPOSE : Work out the string for the indicated language.
*/
LOCAL CHAR *aci_bat_lang_str (T_ACI_LAN_SUP *CLang)
{
  UBYTE i;

  if (CLang==NULL)
    return(NULL);

  /*
  *   If a string is provided, use that.
  */
  if (CLang->str)
    return(CLang->str);

  /*
  *   GSM 07.07 says that "AUTO" should be used for automatic mode.
  */  
  if (CLang->lng==CLAN_LNG_AUT)
    return("AUTO");

  /*
  *   Use the lookup table 'lngs' to find the string.
  */
  for (i=0;lngs[i].str;i++)
  {
    if (CLang->lng==lngs[i].lng)
      return(lngs[i].str);
  }

  return(NULL);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_OK              |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_OK(
  T_ACI_AT_CMD cmd)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_no_parameter dummy;

  TRACE_FUNCTION ("rBAT_OK()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  if (cmd EQ AT_CMD_D)
  {
    /*
    *   We are not waiting for a final response to ATD any more.
    */
    src_infos->bat_client[src_infos->active_client].atd_live=FALSE;
  }

  resp.ctrl_response=BAT_RES_AT_OK;

  resp.response.ptr_at_ok = &dummy;
  dummy.bat_dummy = 0xFF;

  if (src_infos->bat_client[src_infos->active_client].curCmd EQ BATC_ABORT_COMMAND_CNF)
  {
    T_BATC_confirm confirm;
    T_BATC_abort_cmd abort_cmd;
    confirm.rsp_params  = BATC_ABORT_COMMAND_CNF;        
    abort_cmd.client_id = src_infos->active_client;  
    confirm.rsp.ptr_bat_abort_command_cnf = &abort_cmd;
    aci_bat_send(src_infos,(T_BAT_cmd_response *)&confirm);
    return;
  }

#ifdef _SIMULATION_
  src_infos->bat_client[src_infos->active_client].curCmd = (T_BAT_ctrl_params)-1;
#endif

  aci_bat_send(src_infos,&resp);

  /* check for possible next command queued */
  aci_bat_run_cmd (src_infos);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_CONNECT         |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_CONNECT(
  T_ACI_AT_CMD cmdId,
  T_ACI_BS_SPEED speed,
  SHORT cId,
  BOOL flow_cntr)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_res_at_connect connect_data;
  T_BAT_cmd_response resp;

  TRACE_FUNCTION ("rBAT_CONNECT()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  /*
  *   We are not waiting for a final response to ATD any more.
  */
  src_infos->bat_client[src_infos->active_client].atd_live=FALSE;

  resp.ctrl_response=BAT_RES_AT_CONNECT;
  resp.response.ptr_at_connect=&connect_data;

  /*
  *   The ACI and BAT versions of 'speed' are quite a bit different,
  *   so we need this conversion. Note that we will be losing
  *   the "cmdId" and "cId" as these are not in the BAT.
  */
  switch(speed)
  {
    default:
    case BS_SPEED_NotPresent:
    case BS_SPEED_AUTO:
    case BS_SPEED_28800_V110:
      connect_data.data_rate=BAT_AT_CONNECT_RATE_NOT_PRESENT;
      break;

    case BS_SPEED_300_V21:
    case BS_SPEED_300_V110:
      connect_data.data_rate=BAT_AT_CONNECT_RATE_300;
      break;

    case BS_SPEED_1200_V22:
    case BS_SPEED_1200_75_V23:
    case BS_SPEED_1200_V120:
    case BS_SPEED_1200_V110:
      connect_data.data_rate=BAT_AT_CONNECT_RATE_1200;
      break;

    case BS_SPEED_2400_V22bis:
    case BS_SPEED_2400_V26ter:
    case BS_SPEED_2400_V120:
    case BS_SPEED_2400_V110:
      connect_data.data_rate=BAT_AT_CONNECT_RATE_2400;
      break;

    case BS_SPEED_4800_V32:
    case BS_SPEED_4800_V120:
    case BS_SPEED_4800_V110:
      connect_data.data_rate=BAT_AT_CONNECT_RATE_4800;
      break;

    case BS_SPEED_9600_V32:
    case BS_SPEED_9600_V34:
    case BS_SPEED_9600_V120:
    case BS_SPEED_9600_V110:
      connect_data.data_rate=BAT_AT_CONNECT_RATE_9600;
      break;

    case BS_SPEED_14400_V34:
    case BS_SPEED_14400_V120:
    case BS_SPEED_14400_V110:
      connect_data.data_rate=BAT_AT_CONNECT_RATE_14400;
      break;

    case BS_SPEED_19200_V110:
      connect_data.data_rate=BAT_AT_CONNECT_RATE_19200;
      break;

    case BS_SPEED_38400_V110:
      connect_data.data_rate=BAT_AT_CONNECT_RATE_38400;
      break;
  }

  aci_bat_send(src_infos,&resp);
  
  /* check for possible next command queued */
  aci_bat_run_cmd (src_infos);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCME         |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCME(
  T_ACI_AT_CMD cmdId,
  T_ACI_CME_ERR err)
{
  T_BAT_cmd_response resp;
  T_BAT_res_plus_cme_error error_data;
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;

  TRACE_FUNCTION ("rBAT_PlusCME()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_PLUS_CME_ERROR;
  resp.response.ptr_plus_cme_error=&error_data;

  /*
  *   This relies on T_ACI_CME_ERR being the same as
  *   T_BAT_plus_cme_error_error, which (apart from a couple of
  *   omissions in each enumeration) it is.
  */
  resp.response.ptr_plus_cme_error->error=(T_BAT_plus_cme_error_error)err;

  aci_bat_send(src_infos,&resp);

  /* check for possible next command queued */
  aci_bat_run_cmd (src_infos); 
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_NO_CARRIER      |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_NO_CARRIER(
  T_ACI_AT_CMD cmdId,
  SHORT cId)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_no_parameter dummy;
  
  TRACE_FUNCTION ("rBAT_NO_CARRIER()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  /*
  *   We are not waiting for a final response to ATD any more.
  */
  src_infos->bat_client[src_infos->active_client].atd_live=FALSE;

  resp.ctrl_response = BAT_RES_AT_NO_CARRIER_FINAL;
  resp.response.ptr_at_no_carrier_final = &dummy;
  dummy.bat_dummy = 0xFF;

  aci_bat_send(src_infos,&resp);

  /* check for possible next command queued */
  aci_bat_run_cmd (src_infos);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCRING       |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCRING(
  T_ACI_CRING_MOD mode,
  T_ACI_CRING_TYP type1,
  T_ACI_CRING_TYP type2)
{
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_cring cring_data;
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;

  TRACE_FUNCTION ("rBAT_PlusCRING()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_CRING;
  resp.response.ptr_plus_cring=&cring_data;

  /*
  *   This relies on T_ACI_CRING_TYP being the same as
  *   T_BAT_cring_type/T_BAT_plus_cring_type2.
  */
  cring_data.type1=(T_BAT_cring_type)type1;
  cring_data.type2=(T_BAT_plus_cring_type2)type2;

  /*
  *   This relies on T_ACI_CRING_MOD being the same as
  *   T_BAT_plus_cring_alt.
  */
  cring_data.alt=(T_BAT_plus_cring_alt)mode;

  /*
  *   Mark as not present all the information in the BAT message
  *   that we don't have.
  */
  cring_data.v_pdp_addr=FALSE;
  cring_data.v_l2p=FALSE;
  cring_data.pdp_type=BAT_PDP_TYPE_NOT_PRESENT;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusDR          |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusDR(
  T_ACI_DR_TYP type)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_PlusDR() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_PlusDR() - FAKE");
  rCI_PlusDR(type);

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCR          |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCR(
  T_ACI_CR_SERV service)
{
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_cr cr_data;
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  CHAR *s;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PlusCR()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_CR;
  resp.response.ptr_res_plus_cr=&cr_data;

  switch(service)
  {
    case CR_SERV_Async:
      s="ASYNC";
      break;

    case CR_SERV_Sync:
      s="SYNC";
      break;
      
    case CR_SERV_RelAsync:
      s="REL ASYNC";
      break;

    case CR_SERV_RelSync:
      s="REL SYNC";
      break;

#ifdef GPRS
    case CR_SERV_GPRS:
      s="GPRS";
      break;
#endif

    default:
      /*
      *   Unrecognised value, get out now.
      */
      return;    
  }

  len=strlen(s);

  /*
  *   Check that we have enough room in the BAT structure, if we
  *   haven't we may as well give up at this point.
  */
  if (len>BAT_MAX_CR_SERV_LEN)
    return;

  /*
  *   Copy the data into the BAT structure and set the counter.
  */
  memcpy(cr_data.serv,s,BAT_MAX_CR_SERV_LEN);
  cr_data.c_serv=(U8)len;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCPIN        |
+--------------------------------------------------------------------+

  PURPOSE : Response to qBAT_PlusCPIN(). Also see simactivated_cpinresult().
*/
GLOBAL void rBAT_PlusCPIN(
  T_ACI_CPIN_RSLT code)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_cpin cpin_data;
 
  TRACE_FUNCTION ("rBAT_PlusCPIN()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_QUE_PLUS_CPIN;
  resp.response.ptr_que_plus_cpin=&cpin_data;

  /*
  *   Warning - this assumes that T_ACI_CPIN_RSLT and
  *   T_BAT_VAL_plus_cpin_code are eqivalent. They are, except that
  *   T_ACI_CPIN_RSLT has extra values not in the BAT.
  */
  resp.response.ptr_que_plus_cpin->code=(T_BAT_VAL_plus_cpin_code)code; 

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCOPS        |
+--------------------------------------------------------------------+

  PURPOSE : See cmhMM_NetworkLst() for how this is used.
*/
GLOBAL void rBAT_PlusCOPS(
  SHORT lastIdx,
  T_ACI_COPS_OPDESC *operLst)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_tst_plus_cops cops_data;
  USHORT n;

  TRACE_FUNCTION ("rBAT_PlusCOPS()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_TST_PLUS_COPS;
  resp.response.ptr_tst_plus_cops=&cops_data;

  /*
  *   This has delivered a list, however the BAT response only
  *   allows for single items. So we must send each one 
  *   individually. The use of null values of longOper and
  *   shortOper as list terminators is as in rAT_PlusCOPS().
  */
  n=0;

  while ((operLst[n].longOper) && (operLst[n].shortOper))
  {
    /*
    *   This assumes that T_BAT_VAL_plus_cops_status and T_ACI_COPS_STAT
    *   are identical (currently they are).
    */
    cops_data.status=(T_BAT_plus_cops_status)operLst[n].status;

    /*
    *   Need to check this. Are all the operator names necessarily
    *   present?
    */
    strncpy((CHAR *)cops_data.long_oper,operLst[n].longOper,BAT_MAX_COPS_LONG_OPER_LEN);
    cops_data.v_long_oper=TRUE;
    cops_data.c_long_oper=strlen((CHAR*)cops_data.long_oper);

    strncpy((CHAR *)cops_data.short_oper,operLst[n].shortOper,BAT_MAX_COPS_SHORT_OPER_LEN);
    cops_data.v_short_oper=TRUE;
    cops_data.c_short_oper=strlen((CHAR*)cops_data.short_oper);

    strncpy((CHAR *)cops_data.num_oper,operLst[n].numOper,BAT_MAX_COPS_NUM_OPER_LEN);
    cops_data.v_num_oper=TRUE;
    cops_data.c_num_oper=strlen((CHAR*)cops_data.num_oper);

    aci_bat_send(src_infos,&resp);
    
    n++;
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCOPS     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCOPS(
  SHORT lastIdx,
  T_ACI_COPS_OPDESC *operLst)
{

#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_PercentCOPS() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_PercentCOPS() - FAKE");
  rCI_PercentCOPS(lastIdx,operLst);

#endif

}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCREG        |
+--------------------------------------------------------------------+

  PURPOSE : Notification of registration status. There is no +CREG in
            BAT, so we use %CREG instead.
*/
GLOBAL void rBAT_PlusCREG(
  T_ACI_CREG_STAT status,
  USHORT lac,
  USHORT cid)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_creg creg_data;

  TRACE_FUNCTION ("rBAT_PlusCREG()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_CREG;
  resp.response.ptr_res_percent_creg=&creg_data;

  /*
  *   This relies on T_ACI_CREG_STAT and T_BAT_percent_creg_stat being
  *   identical.
  */
  creg_data.stat=(T_BAT_percent_creg_stat)status;

  creg_data.lac=(S32)lac;
  creg_data.ci=(S32)cid;
  creg_data.gprs_ind=BAT_P_CREG_GPRS_IND_UNKNOWN;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCCWA        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCCWA(
  T_ACI_CLSSTAT *clsStat,
  CHAR *number,
  T_ACI_TOA *type,
  U8 validity,
  T_ACI_CLASS class_type,
#ifdef NO_ASCIIZ
  T_ACI_PB_TEXT *alpha)
#else
  CHAR *alpha)
#endif
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_ccwa ccwa_data;
  T_BAT_res_set_plus_ccwa ccwa_q_data;
  T_ACI_CLASS test_class;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PlusCCWA()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  if(clsStat)          /*Callback for sBAT_PlusCCWA guery (mode 2)*/
  {
    resp.ctrl_response = BAT_RES_SET_PLUS_CCWA;
    resp.response.ptr_set_plus_ccwa = &ccwa_q_data;
    
    if (clsStat->status EQ STATUS_Active)
    {
      //src_params->curAtCmd = AT_CMD_NONE;
      test_class = 1;
      while( test_class < 2*CLASS_Fax )
      {
        if( clsStat->class_type & test_class )
        {
          TRACE_EVENT_P1("test_class: %d", test_class);
          ccwa_q_data.status = clsStat->status; 
          ccwa_q_data.bearer_class = test_class; 

          aci_bat_send(src_infos,&resp);          
        }
        test_class *= 2; /* test next class */
      }
    }
    else
    {

      ccwa_q_data.status = clsStat->status; 
      ccwa_q_data.bearer_class = BAT_CCWA_CLASS_NOT_PRESENT; 

      aci_bat_send(src_infos,&resp);          
    }
    
  }
  else 
  {
  resp.ctrl_response=BAT_RES_UNS_PLUS_CCWA;
  resp.response.ptr_res_plus_ccwa=&ccwa_data;

  if (number==NULL)
  {
    ccwa_data.number[0]=0;
    ccwa_data.c_number=0;
  }
  else
  {
    len=strlen(number);

    if (len<=BAT_MAX_CCWA_NUMBER_LEN)
    {
      memcpy(ccwa_data.number,number,BAT_MAX_CCWA_NUMBER_LEN);
      ccwa_data.c_number=(U8)len;
    }
    else
    {
      /*
      *   This is highly unlikely to happen, but if the number is too
      *   big, then put as many digits as will fit in the BAT structure
      *   from the END of the number.
      */
      memcpy(
        ccwa_data.number,
        number+(len-BAT_MAX_CCWA_NUMBER_LEN),
        BAT_MAX_CCWA_NUMBER_LEN);

      ccwa_data.c_number=(U8)BAT_MAX_CCWA_NUMBER_LEN;
    }
  }

  if (type==NULL)
  {
    /*
    *   This is mandatory in the BAT so we have to do something here.
    */
    T_ACI_TOA t;

    t.npi=NPI_Unknown;
    t.ton=TON_Unknown;

    ccwa_data.type=(U8)toa_merge(t);
  }
  else
  {
    ccwa_data.type=(U8)toa_merge(*type);
  }

  /*
  *   This relies on T_ACI_CLASS being equivalent to
  *   T_BAT_plus_ccwa_bearer_class.
  */
      ccwa_data.bearer_class=(T_BAT_plus_ccwa_bearer_class)class_type;
  
  /*
  *   Alphanumeric data
  */
  if (alpha!=NULL)
  {
    USHORT len=0;

    ccwa_data.v_alpha=TRUE;

#ifdef NO_ASCIIZ

      utl_chsetFromSim(
      alpha->data,
      alpha->len,
      ccwa_data.alpha,
      BAT_MAX_PHB_NUM_LEN,
      &len,
      GSM_ALPHA_Def);

#else

    utl_chsetFromSim(
      alpha,
      strlen(alpha),
      ccwa_data.alpha,
      BAT_MAX_PHB_NUM_LEN,
      &len,
      GSM_ALPHA_Int);

#endif

    ccwa_data.c_alpha=(U8)len;
  }
  else
  {
    ccwa_data.v_alpha=FALSE;
  }

  ccwa_data.cli=(T_BAT_cli)validity;

  aci_bat_send(src_infos,&resp);
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCLIP        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCLIP(
  T_ACI_CLIP_STAT stat,
  CHAR *number,
  T_ACI_TOA * type,
  U8 validity,
  CHAR *subaddr,
  T_ACI_TOS *satype,
#ifdef NO_ASCIIZ
  T_ACI_PB_TEXT *alpha)
#else
  CHAR *alpha)
#endif /*NO_ASCIIZ*/
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_clip clip_data;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PlusCLIP()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_CLIP;
  resp.response.ptr_res_plus_clip=&clip_data;

  if (number==NULL)
  {
    clip_data.number[0]=0;
    clip_data.c_number=0;
  }
  else
  {
    len=strlen(number);

    if (len<=BAT_MAX_CLIP_NUMBER_LEN)
    {
      memcpy(clip_data.number,number,BAT_MAX_CLIP_NUMBER_LEN);
      clip_data.c_number=(U8)len;
    }
    else
    {
      /*
      *   This is highly unlikely to happen, but if the number is too
      *   big, then put as many digits as will fit in the BAT structure
      *   from the END of the number.
      */
      memcpy(
        clip_data.number,
        number+(len-BAT_MAX_CLIP_NUMBER_LEN),
        BAT_MAX_CLIP_NUMBER_LEN);

      clip_data.c_number=(U8)BAT_MAX_CLIP_NUMBER_LEN;
    }
  }

  if (type==NULL)
  {
    /*
    *   This is mandatory in the BAT so we have to do something here.
    */
    T_ACI_TOA t;

    t.npi=NPI_Unknown;
    t.ton=TON_Unknown;

    clip_data.type=(U8)toa_merge(t);
  }
  else
  {
    clip_data.type=(U8)toa_merge(*type);
  }

  if (subaddr==NULL)
  {
    clip_data.v_subaddr=FALSE;
    clip_data.satype=-1;
  }
  else
  {
    clip_data.v_subaddr=TRUE;

    if (satype==NULL)
      clip_data.satype=-1;
    else
      clip_data.satype=(S16)tos_merge(*satype);

    len=strlen(subaddr);

    /*
    *   Easiest thing to do is copy as much subaddress data as the
    *   BAT structure can take. The length field will ensure that
    *   there are no problems, and will result in the subaddress
    *   being truncated if it is too long.
    */
    memcpy(clip_data.subaddr,subaddr,BAT_MAX_SUBADDR_LENGTH);

    if (len>BAT_MAX_SUBADDR_LENGTH)
      clip_data.c_subaddr=BAT_MAX_SUBADDR_LENGTH;
    else
      clip_data.c_subaddr=len;
  }

  clip_data.cli=(T_BAT_cli)validity;

  /*
  *   Alphanumeric data
  */
  if (alpha!=NULL)
  {
    USHORT len;

    clip_data.v_alpha=TRUE;

#ifdef NO_ASCIIZ

    utl_chsetFromSim(
      alpha->data,
      alpha->len,
      (UBYTE *)clip_data.alpha,
      BAT_MAX_PHB_NUM_LEN,
      &len,
      GSM_ALPHA_Def);

#else

    utl_chsetFromSim(
      alpha,
      strlen(alpha),
      (UBYTE *)clip_data.alpha,
      BAT_MAX_PHB_NUM_LEN,
      &len,
      GSM_ALPHA_Def);

#endif /*NO_ASCIIZ*/

    clip_data.c_alpha=(U8)len;
  }
  else
  {
    clip_data.v_alpha=FALSE;
  }

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCDIP        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCDIP(CHAR *number,
                          T_ACI_TOA * type,
                          CHAR *subaddr,
                          T_ACI_TOS *satype)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_cdip cdip_data;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PlusCDIP()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_CDIP;
  resp.response.ptr_res_plus_cdip=&cdip_data;

  if (number==NULL)
  {
    cdip_data.number[0]=0;
    cdip_data.c_number=0;
  }
  else
  {
    len=strlen(number);

    if (len<=BAT_MAX_CDIP_NUMBER_LEN)
    {
      memcpy(cdip_data.number,number,BAT_MAX_CDIP_NUMBER_LEN);
      cdip_data.c_number=(U8)len;
    }
    else
    {
      /*
      *   This is highly unlikely to happen, but if the number is too
      *   big, then put as many digits as will fit in the BAT structure
      *   from the END of the number.
      */
      memcpy(
        cdip_data.number,
        number+(len-BAT_MAX_CDIP_NUMBER_LEN),
        BAT_MAX_CDIP_NUMBER_LEN);

      cdip_data.c_number=(U8)BAT_MAX_CDIP_NUMBER_LEN;
    }
  }

  if (type==NULL)
  {
    /*
    *   This is mandatory in the BAT so we have to do something here.
    */
    T_ACI_TOA t;

    t.npi=NPI_Unknown;
    t.ton=TON_Unknown;

    cdip_data.type=(U8)toa_merge(t);
  }
  else
  {
    cdip_data.type=(U8)toa_merge(*type);
  }

  if (subaddr==NULL)
  {
    cdip_data.v_subaddr=FALSE;
    cdip_data.satype=-1;
  }
  else
  {
    cdip_data.v_subaddr=TRUE;

    if (satype==NULL)
      cdip_data.satype=-1;
    else
      cdip_data.satype=(S16)tos_merge(*satype);

    len=strlen(subaddr);

    /*
    *   Easiest thing to do is copy as much subaddress data as the
    *   BAT structure can take. The length field will ensure that
    *   there are no problems, and will result in the subaddress
    *   being truncated if it is too long.
    */
    memcpy(cdip_data.subaddr,subaddr,BAT_MAX_SUBADDR_LENGTH);

    if (len>BAT_MAX_SUBADDR_LENGTH)
      cdip_data.c_subaddr=BAT_MAX_SUBADDR_LENGTH;
    else
      cdip_data.c_subaddr=len;
  }

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCOLP        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
EXTERN void rBAT_PlusCOLP(
  T_ACI_COLP_STAT stat,
  CHAR *number,
  T_ACI_TOA *type,
  CHAR *subaddr,
  T_ACI_TOS *satype,
#ifdef NO_ASCIIZ
  T_ACI_PB_TEXT *alpha)
#else
  CHAR *alpha)
#endif /*NO_ASCIIZ*/
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_colp colp_data;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PlusCOLP()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_COLP;
  resp.response.ptr_res_plus_colp=&colp_data;

  if (number==NULL)
  {
    colp_data.v_number=FALSE;
  }
  else
  {
    len=strlen(number);

    colp_data.v_number=TRUE;

    if (len<=BAT_MAX_COLP_NUMBER_LEN)
    {
      memcpy(colp_data.number,number,BAT_MAX_COLP_NUMBER_LEN);
      colp_data.c_number=(U8)len;
    }
    else
    {
      /*
      *   This is highly unlikely to happen, but if the number is too
      *   big, then put as many digits as will fit in the BAT structure
      *   from the END of the number.
      */
      memcpy(
        colp_data.number,
        number+(len-BAT_MAX_COLP_NUMBER_LEN),
        BAT_MAX_COLP_NUMBER_LEN);

      colp_data.c_number=(U8)BAT_MAX_COLP_NUMBER_LEN;
    }
  }

  if (type==NULL)
  {
    /*
    *   This is mandatory in the BAT so we have to do something here.
    */
    T_ACI_TOA t;

    t.npi=NPI_Unknown;
    t.ton=TON_Unknown;

    colp_data.type=(U8)toa_merge(t);
  }
  else
  {
    colp_data.type=(U8)toa_merge(*type);
  }

  if (subaddr==NULL)
  {
    colp_data.v_subaddr=FALSE;
    colp_data.satype=-1;
  }
  else
  {
    colp_data.v_subaddr=TRUE;

    if (satype==NULL)
      colp_data.satype=-1;
    else
      colp_data.satype=(S16)tos_merge(*satype);

    len=strlen(subaddr);

    /*
    *   Easiest thing to do is copy as much subaddress data as the
    *   BAT structure can take. The length field will ensure that
    *   there are no problems, and will result in the subaddress
    *   being truncated if it is too long.
    */
    memcpy(colp_data.subaddr,subaddr,BAT_MAX_SUBADDR_LENGTH);

    if (len>BAT_MAX_SUBADDR_LENGTH)
      colp_data.c_subaddr=BAT_MAX_SUBADDR_LENGTH;
    else
      colp_data.c_subaddr=len;
  }

  /*
  *   Alphanumeric data
  */
  if (alpha!=NULL)
  {
    USHORT len;

    colp_data.v_alpha=TRUE;

#ifdef NO_ASCIIZ

    utl_chsetFromSim(
      alpha->data,
      alpha->len,
      (UBYTE *)colp_data.alpha,
      BAT_MAX_COLP_ALPHA_LEN,
      &len,
      GSM_ALPHA_Def);

#else

    utl_chsetFromSim(
      alpha,
      strlen(alpha),
      (UBYTE *)colp_data.alpha,
      BAT_MAX_COLP_ALPHA_LEN,
      &len,
      GSM_ALPHA_Def);

#endif /*NO_ASCIIZ*/

    colp_data.c_alpha=(U8)len;
  }
  else
  {
    colp_data.v_alpha=FALSE;
  }

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCRING_OFF   |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCRING_OFF(
    SHORT cId)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_PlusCRING_OFF() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_PlusCRING_OFF() - FAKE");
  rCI_PlusCRING_OFF(cId);

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCMS         |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCMS(
  T_ACI_AT_CMD cmdId,
  T_ACI_CMS_ERR err,
  T_EXT_CMS_ERROR *conc_error)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_plus_cms_error error_data;

  TRACE_FUNCTION ("rBAT_PlusCMS()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_PLUS_CMS_ERROR;
  resp.response.ptr_plus_cms_error=&error_data;

  /*
  *   This relies on T_ACI_CMS_ERR being the same as
  *   T_BAT_plus_cms_error_err.
  */
  resp.response.ptr_plus_cms_error->err=(T_BAT_plus_cme_error_error)err;

  /*
  *   BAT does not include cmdId or conc_error, so these are
  *   discarded.
  */

  aci_bat_send(src_infos,&resp);

  /* check for possible next command queued */
  aci_bat_run_cmd (src_infos); 
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCSMS        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCSMS(
  T_ACI_CSMS_SERV service,
  T_ACI_CSMS_SUPP mt,
  T_ACI_CSMS_SUPP mo,
  T_ACI_CSMS_SUPP bm)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_csms csms_data;

  TRACE_FUNCTION ("rBAT_PlusCSMS()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_QUE_PLUS_CSMS;
  resp.response.ptr_que_plus_csms=&csms_data;

  /*
  *   This relies on T_ACI_CSMS_SERV being equivalent to
  *   T_BAT_plus_csms_service.
  */
  csms_data.service=(T_BAT_plus_csms_service)service;

  /*
  *   This relies on T_ACI_CSMS_SUPP being equivalent to
  *   T_BAT_plus_csms_mt/mo/bm.
  */
  csms_data.mt=(T_BAT_plus_csms_mt)mt;
  csms_data.mo=(T_BAT_plus_csms_mo)mo;
  csms_data.bm=(T_BAT_plus_csms_bm)bm;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCMGS        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCMGS(
  T_MNSMS_SUBMIT_CNF *mnsms_submit_cnf)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_plus_cmgs cmgs_data;

  TRACE_FUNCTION ("rBAT_PlusCMGS()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_SET_PLUS_CMGS;
  resp.response.ptr_set_plus_cmgs=&cmgs_data;

  /*
  *   Note that all the rest of the information is lost, as it is
  *   not in the BAT.
  */
  cmgs_data.mr=(U8)mnsms_submit_cnf->tp_mr;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCMSS        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCMSS(
  T_MNSMS_SUBMIT_CNF *mnsms_submit_cnf)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_plus_cmss cmss_data;
  UBYTE len = 0;
  UBYTE sca_len = 0;
  UBYTE ackpdu_len = 0;

  TRACE_FUNCTION ("rBAT_PlusCMSS()");

  if (mnsms_submit_cnf EQ NULL)
    return;

  /*
  *   Calculate the PDU length in bytes from the number in bits.
  */
  len=((mnsms_submit_cnf->sms_sdu.l_buf+7)/8);

  /*
  *   The PDU data is mandatory, and a truncated version would be
  *   meaningless, so if it won't fit in the BAT message we should
  *   give up. This shouldn't happen anyway.
  */
  if (len>BAT_MAX_SM_LEN)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_SET_PLUS_CMSS;
  resp.response.ptr_set_plus_cmss=&cmss_data;


  cmss_data.mr=mnsms_submit_cnf->tp_mr;

  cmss_data.c_ackpdu = 0;

  if (smsShrdPrm.CSMSservice EQ CSMS_SERV_GsmPh2Plus)
  {
    if (mnsms_submit_cnf->sms_sdu.l_buf)
    {
      sca_len = mnsms_submit_cnf->sms_sdu.buf[0] + 1;
      ackpdu_len = len - sca_len;
      /*
      *   Now copy the PDU into the BAT structure without SCA field.
      */
      memcpy(cmss_data.ackpdu,&mnsms_submit_cnf->sms_sdu.buf[sca_len],ackpdu_len);
      cmss_data.c_ackpdu = ackpdu_len;
    }
  }
  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCMGW        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCMGW(
  UBYTE index,
  UBYTE numSeg)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_plus_cmgw cmgw_data;

  TRACE_FUNCTION ("rBAT_PlusCMGW()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_SET_PLUS_CMGW;
  resp.response.ptr_set_plus_cmgw=&cmgw_data;

  cmgw_data.index=(U8)index;

  /*
  *   numSeg is lost as it is not in the BAT.
  */

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCDS         |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCDS(
  T_MNSMS_STATUS_IND *mnsms_status_ind)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_cds cds_data;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PlusCDS()");

  if (mnsms_status_ind==NULL)
    return;

  /*
  *   Calculate the PDU length in bytes from the number in bits.
  */
  len=((mnsms_status_ind->sms_sdu.l_buf+7)/8);

  /*
  *   The PDU data is mandatory, and a truncated version would be
  *   meaningless, so if it won't fit in the BAT message we should
  *   give up. This shouldn't happen anyway.
  */
  if (len>BAT_MAX_SM_LEN)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_CDS;
  resp.response.ptr_res_plus_cds=&cds_data;

  /*
  *   Now copy the PDU into the BAT structure.
  */
  memcpy(cds_data.pdu,mnsms_status_ind->sms_sdu.buf,len);
  cds_data.c_pdu=(U8)len;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCMGC        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCMGC(
  T_MNSMS_COMMAND_CNF *mnsms_command_cnf)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_plus_cmgc cmgc_data;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PlusCMGC()");

  if (mnsms_command_cnf==NULL)
    return;

  /*
  *   Calculate the PDU length in bytes from the number in bits.
  */
  len=((mnsms_command_cnf->sms_sdu.l_buf+7)/8);

  /*
  *   The PDU data is mandatory, and a truncated version would be
  *   meaningless, so if it won't fit in the BAT message we should
  *   give up. This shouldn't happen anyway.
  */
  if (len>BAT_MAX_SM_LEN)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_SET_PLUS_CMGC;
  resp.response.ptr_set_plus_cmgc=&cmgc_data;

  cmgc_data.mr=mnsms_command_cnf->tp_mr;

  /*
  *   Now copy the PDU into the BAT structure.
  */
  memcpy(cmgc_data.ackpdu,mnsms_command_cnf->sms_sdu.buf,len);
  cmgc_data.c_ackpdu=(U8)len;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCMGD        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCMGD(void)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_PlusCMGD() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_PlusCMGD() - FAKE");
  rCI_PlusCMGD();

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCMGR        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCMGR(
  T_MNSMS_READ_CNF *mnsms_read_cnf,
  T_ACI_CMGR_CBM *cbm)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_plus_cmgr cmgr_data;
  T_ACI_PB_TEXT alpha;
  T_ACI_SMS_STAT stat;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PlusCMGR()");

  if (mnsms_read_cnf==NULL)
    return;

  /*
  *   Calculate the PDU length in bytes from the number in bits.
  */
  len=((mnsms_read_cnf->sms_sdu.l_buf+7)/8);

  /*
  *   The PDU data is mandatory, and a truncated version would be
  *   meaningless, so if it won't fit in the BAT message we should
  *   give up. This shouldn't happen anyway.
  */
  if (len>BAT_MAX_SM_LEN)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_SET_PLUS_CMGR;
  resp.response.ptr_set_plus_cmgr=&cmgr_data;

  /*
  *   Now copy the PDU into the BAT structure.
  */
  memcpy(cmgr_data.pdu,mnsms_read_cnf->sms_sdu.buf,len);
  cmgr_data.c_pdu=len;

  /*
  *   Convert status from PSA type to CMH type.
  */
  cmhSMS_getStatCmh(mnsms_read_cnf->status,&stat);

  /*
  *   This relies on T_ACI_SMS_STAT and T_BAT_sms_stat being equivalent
  *   (apart from the extra 'invalid' value that the ACI has).
  */
  if (stat==SMS_STAT_Invalid)
    cmgr_data.sms_stat=BAT_STAT_NOT_PRESENT;
  else
    cmgr_data.sms_stat=(T_BAT_sms_stat)stat;

  /*
  *   Try and get the alphanumeric (phonebook) data.
  */
  cmhSMS_getPhbEntry(mnsms_read_cnf->sms_sdu.buf,&alpha,stat);

  if (alpha.len)
  {
    USHORT len_cvtd_alpha;

    utl_chsetFromGsm(
      (UBYTE*)alpha.data,
      alpha.len,
      (UBYTE*)cmgr_data.alpha,
      BAT_MAX_CMGR_ALPHA,
      &len_cvtd_alpha,
      GSM_ALPHA_Def);

    cmgr_data.c_alpha=(U8)len_cvtd_alpha;
    cmgr_data.v_alpha=TRUE;

    cmgr_data.alpha_cs=aci_bat_cs_get(src_infos);
  }
  else
  {
    cmgr_data.v_alpha=FALSE;
  }

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCMGR     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCMGR(
  T_MNSMS_READ_CNF *mnsms_read_cnf,
  T_ACI_CMGR_CBM *cbm)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_percent_cmgr cmgr_data;
  T_ACI_PB_TEXT alpha;
  T_ACI_SMS_STAT stat;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PercentCMGR()");

  if (mnsms_read_cnf==NULL)
    return;

  /*
  *   Calculate the PDU length in bytes from the number in bits.
  */
  len=((mnsms_read_cnf->sms_sdu.l_buf+7)/8);

  /*
  *   The PDU data is mandatory, and a truncated version would be
  *   meaningless, so if it won't fit in the BAT message we should
  *   give up. This shouldn't happen anyway.
  */
  if (len>BAT_MAX_SM_LEN)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_SET_PERCENT_CMGR;
  resp.response.ptr_set_percent_cmgr=&cmgr_data;

  /*
  *   Now copy the PDU into the BAT structure.
  */
  memcpy(cmgr_data.pdu,mnsms_read_cnf->sms_sdu.buf,len);
  cmgr_data.c_pdu=len;

  /*
  *   Convert status from PSA type to CMH type.
  */
  cmhSMS_getStatCmh(mnsms_read_cnf->status,&stat);

  /*
  *   This relies on T_ACI_SMS_STAT and T_BAT_sms_stat being equivalent
  *   (apart from the extra 'invalid' value that the ACI has).
  */
  if (stat==SMS_STAT_Invalid)
    cmgr_data.sms_stat=BAT_STAT_NOT_PRESENT;
  else
    cmgr_data.sms_stat=(T_BAT_sms_stat)stat;

  /*
  *   Try and get the alphanumeric (phonebook) data.
  */
  cmhSMS_getPhbEntry(mnsms_read_cnf->sms_sdu.buf,&alpha,stat);

  if (alpha.len)
  {
    USHORT len_cvtd_alpha;

    utl_chsetFromGsm(
      (UBYTE*)alpha.data,
      alpha.len,
      (UBYTE*)cmgr_data.alpha,
      BAT_MAX_CMGR_ALPHA,
      &len_cvtd_alpha,
      GSM_ALPHA_Def);

    cmgr_data.c_alpha=(U8)len_cvtd_alpha;
    cmgr_data.v_alpha=TRUE;

    cmgr_data.alpha_cs=aci_bat_cs_get(src_infos);
  }
  else
  {
    cmgr_data.v_alpha=FALSE;
  }

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCMGL        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCMGL(
  T_MNSMS_READ_CNF *mnsms_read_cnf)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_plus_cmgl cmgl_data;
  T_ACI_PB_TEXT alpha;
  T_ACI_SMS_STAT stat;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PlusCMGL()");

  if (mnsms_read_cnf==NULL)
    return;

  /*
  *   Calculate the PDU length in bytes from the number in bits.
  */
  len=((mnsms_read_cnf->sms_sdu.l_buf+7)/8);

  /*
  *   The PDU data is mandatory, and a truncated version would be
  *   meaningless, so if it won't fit in the BAT message we should
  *   give up. This shouldn't happen anyway.
  */
  if (len>BAT_MAX_SM_LEN)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_SET_PLUS_CMGL;
  resp.response.ptr_set_plus_cmgl=&cmgl_data;

  cmgl_data.sms_index=(U16)mnsms_read_cnf->rec_num;

  /*
  *   Now copy the PDU into the BAT structure.
  */
  memcpy(cmgl_data.pdu,mnsms_read_cnf->sms_sdu.buf,len);
  cmgl_data.c_pdu=len;

  /*
  *   Try and get the alphanumeric (phonebook) data.
  */
  cmhSMS_getStatCmh(mnsms_read_cnf->status,&stat);
  cmhSMS_getPhbEntry(mnsms_read_cnf->sms_sdu.buf,&alpha,stat);

  if (alpha.len)
  {
    USHORT len_cvtd_alpha;

    utl_chsetFromGsm(
      (UBYTE*)alpha.data,
      alpha.len,
      (UBYTE*)cmgl_data.alpha,
      BAT_MAX_CMGL_ALPHA,
      &len_cvtd_alpha,
      GSM_ALPHA_Def);

    cmgl_data.c_alpha=(U8)len_cvtd_alpha;
    cmgl_data.v_alpha=TRUE;

    cmgl_data.alpha_cs=aci_bat_cs_get(src_infos);
  }
  else
  {
    cmgl_data.v_alpha=FALSE;
  }

  /*
  *   This relies on T_ACI_SMS_STAT and T_BAT_plus_cmgl_stat being equivalent
  *   (apart from the extra 'invalid' value that the ACI has).
  */
  if (stat==SMS_STAT_Invalid)
    cmgl_data.stat=BAT_STAT_NOT_PRESENT;
  else
    cmgl_data.stat=(T_BAT_plus_cmgl_stat)stat;

  aci_bat_send(src_infos,&resp);
}


/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCMGL     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCMGL(
  T_MNSMS_READ_CNF *mnsms_read_cnf)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_percent_cmgl cmgl_data;
  T_ACI_PB_TEXT alpha;
  T_ACI_SMS_STAT stat;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PercentCMGL()");

  if (mnsms_read_cnf==NULL)
    return;

  /*
  *   Calculate the PDU length in bytes from the number in bits.
  */
  len=((mnsms_read_cnf->sms_sdu.l_buf+7)/8);

  /*
  *   The PDU data is mandatory, and a truncated version would be
  *   meaningless, so if it won't fit in the BAT message we should
  *   give up. This shouldn't happen anyway.
  */
  if (len>BAT_MAX_SM_LEN)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_SET_PERCENT_CMGL;
  resp.response.ptr_set_percent_cmgl=&cmgl_data;

  cmgl_data.sms_index=(U16)mnsms_read_cnf->rec_num;

  /*
  *   Now copy the PDU into the BAT structure.
  */
  memcpy(cmgl_data.pdu,mnsms_read_cnf->sms_sdu.buf,len);
  cmgl_data.c_pdu=len;

  /*
  *   Try and get the alphanumeric (phonebook) data.
  */
  cmhSMS_getStatCmh(mnsms_read_cnf->status,&stat);
  cmhSMS_getPhbEntry(mnsms_read_cnf->sms_sdu.buf,&alpha,stat);

  if (alpha.len)
  {
    USHORT len_cvtd_alpha;

    utl_chsetFromGsm(
      (UBYTE*)alpha.data,
      alpha.len,
      (UBYTE*)cmgl_data.alpha,
      BAT_MAX_CMGL_ALPHA,
      &len_cvtd_alpha,
      GSM_ALPHA_Def);

    cmgl_data.c_alpha=(U8)len_cvtd_alpha;
    cmgl_data.v_alpha=TRUE;

    cmgl_data.alpha_cs=aci_bat_cs_get(src_infos);
  }
  else
  {
    cmgl_data.v_alpha=FALSE;
  }

  /*
  *   This relies on T_ACI_SMS_STAT and T_BAT_plus_cmgl_stat being equivalent
  *   (apart from the extra 'invalid' value that the ACI has).
  */
  if (stat==SMS_STAT_Invalid)
    cmgl_data.stat=BAT_STAT_NOT_PRESENT;
  else
    cmgl_data.stat=(T_BAT_plus_cmgl_stat)stat;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCMTI        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCMTI(
  T_ACI_SMS_STOR mem,
  UBYTE index)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_cmti cmti_data;

  TRACE_FUNCTION ("rBAT_PlusCMTI()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_CMTI;
  resp.response.ptr_res_plus_cmti=&cmti_data;

  /*
  *   This relies on T_ACI_SMS_STOR being equivalent to T_BAT_sms_mem.
  */
  cmti_data.sms_mem=(T_BAT_sms_mem)mem;

  cmti_data.sms_index=(U16)index;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCMT         |
+--------------------------------------------------------------------+

  PURPOSE : Report an incoming mobile terminated message.
*/
GLOBAL void rBAT_PlusCMT(
  T_MNSMS_MESSAGE_IND *msg)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_cmt cmt_data;
  UBYTE len;
  T_ACI_PB_TEXT alpha;
  T_ACI_SMS_STAT stat;
  
  TRACE_FUNCTION ("rBAT_PlusCMT()");

  /*
  *   This shouldn't happen, but check anyway.
  */
  if (msg==NULL)
    return;

  /*
  *   Calculate the PDU length in bytes from the number in bits.
  */
  len=((msg->sms_sdu.l_buf+7)/8);

  /*
  *   The PDU data is mandatory, and a truncated version would be
  *   meaningless, so if it won't fit in the BAT message we should
  *   give up. This shouldn't happen anyway.
  */
  if (len>BAT_MAX_SM_LEN)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_CMT;
  resp.response.ptr_res_plus_cmt=&cmt_data;

  /*
  *   Now copy the PDU data into the BAT structure, secure in the
  *   knowledge that we have enough room due to the check earlier.
  */
  memcpy(cmt_data.pdu,&msg->sms_sdu.buf,len);
  cmt_data.c_pdu=(U8)len;

  /*
  *   Try and get the alphanumeric (phonebook) data.
  */
  cmhSMS_getStatCmh(msg->status,&stat);
  cmhSMS_getPhbEntry(msg->sms_sdu.buf,&alpha,stat);

  if (alpha.len)
  {
    USHORT len_cvtd_alpha;

    /*
    *   This relies on T_ACI_CSCS_CHSET being identical to
    *   T_BAT_plus_cscs_cs.
    */
    utl_chsetFromGsm(
      (UBYTE*)alpha.data,
      alpha.len,
      (UBYTE*)cmt_data.alpha,
      BAT_MAX_CMT_ALPHA,
      &len_cvtd_alpha,
      GSM_ALPHA_Def);

    cmt_data.c_alpha=(U8)len_cvtd_alpha;
    cmt_data.v_alpha=TRUE;

    cmt_data.alpha_cs=aci_bat_cs_get(src_infos);
  }
  else
  {
    cmt_data.v_alpha=FALSE;
  }

  aci_bat_send(src_infos,&resp);
}
   
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCBM         |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCBM(
  T_MMI_CBCH_IND *mmi_cbch_ind)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_cbm cbm_data;

  TRACE_FUNCTION ("rBAT_PlusCBM()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_CBM;
  resp.response.ptr_res_plus_cbm=&cbm_data;

  /*
  *   If the data received is too long for the BAT structure it will
  *   effectively be truncated.
  */
  if (mmi_cbch_ind->cbch_len>BAT_MAX_SM_LEN)
    cbm_data.c_pdu=BAT_MAX_SM_LEN;
  else
    cbm_data.c_pdu=(U8)mmi_cbch_ind->cbch_len;

  memcpy(cbm_data.pdu,mmi_cbch_ind->cbch_msg,BAT_MAX_SM_LEN);

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCPMS        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCPMS(
  T_ACI_SMS_STOR_OCC *mem1,
  T_ACI_SMS_STOR_OCC *mem2,
  T_ACI_SMS_STOR_OCC *mem3)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_plus_cpms cpms_data;

  TRACE_FUNCTION ("rBAT_PlusCPMS()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_SET_PLUS_CPMS;
  resp.response.ptr_set_plus_cpms=&cpms_data;

  if (mem1==NULL)
  {
    /*
    *   If this happens we would be required to populate mandatory
    *   parameters without the information to do so. Give up.
    */
    return;
  }

  cpms_data.mem1=(T_BAT_plus_cpms_mem1)mem1->mem;
  cpms_data.used1=(U8)mem1->used;
  cpms_data.total1=(U8)mem1->total;

  if (mem2)
  {
    cpms_data.mem2=(T_BAT_plus_cpms_mem2)mem2->mem;
    cpms_data.used2=(U8)mem2->used;
    cpms_data.total2=(U8)mem2->total;
  }
  else
  {
    cpms_data.mem2=BAT_CPMS_MEM2_NOT_PRESENT;
    cpms_data.used2=0;
    cpms_data.total2=0;
  }

  if (mem3)
  {
    cpms_data.mem3=(T_BAT_plus_cpms_mem3)mem3->mem;
    cpms_data.used3=(U8)mem3->used;
    cpms_data.total3=(U8)mem3->total;
  }
  else
  {
    cpms_data.mem3=BAT_CPMS_MEM3_NOT_PRESENT;
    cpms_data.used3=0;
    cpms_data.total3=0;
  }

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusILRR        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusILRR(
  T_ACI_BS_SPEED speed,
  T_ACI_BS_FRM format,
  T_ACI_BS_PAR parity)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_ilrr ilrr_data;

  TRACE_FUNCTION ("rBAT_PlusILRR()");

  resp.ctrl_response=BAT_RES_UNS_PLUS_ILRR;
  resp.response.ptr_res_plus_ilrr=&ilrr_data;

  /*
  *   T_ACI_BS_SPEED is very different from T_BAT_plus_ilrr_rate,
  *   so we need this conversion.
  */
  switch (speed)
  {
    case BS_SPEED_NotPresent:
      /*
      *   BAT does not include a 'not present' value, but I don't
      *   see any better alternative than this.
      */
      ilrr_data.rate=-1;
      break;

    case BS_SPEED_300_V21:
    case BS_SPEED_300_V110:
      ilrr_data.rate=BAT_ILRR_RATE_300;
      break;

    case BS_SPEED_1200_V22:
    case BS_SPEED_1200_75_V23:
    case BS_SPEED_1200_V120:
    case BS_SPEED_1200_V110:
      ilrr_data.rate=BAT_ILRR_RATE_1200;
      break;

    case BS_SPEED_2400_V22bis:
    case BS_SPEED_2400_V26ter:
    case BS_SPEED_2400_V120:
    case BS_SPEED_2400_V110:
      ilrr_data.rate=BAT_ILRR_RATE_2400;
      break;

    case BS_SPEED_4800_V32:
    case BS_SPEED_4800_V120:
    case BS_SPEED_4800_V110:
      ilrr_data.rate=BAT_ILRR_RATE_4800;
      break;

    case BS_SPEED_9600_V32:
    case BS_SPEED_9600_V34:
    case BS_SPEED_9600_V120:
    case BS_SPEED_9600_V110:
      ilrr_data.rate=BAT_ILRR_RATE_9600;
      break;

    case BS_SPEED_14400_V34:
    case BS_SPEED_14400_V120:
    case BS_SPEED_14400_V110:
      ilrr_data.rate=BAT_ILRR_RATE_14400;
      break;

    case BS_SPEED_19200_V110:
      ilrr_data.rate=BAT_ILRR_RATE_19200;
      break;

    case BS_SPEED_38400_V110:
      ilrr_data.rate=BAT_ILRR_RATE_38400;
      break;

    default:
    case BS_SPEED_AUTO:
    case BS_SPEED_28800_V110:
      ilrr_data.rate=BAT_ILRR_RATE_1;
      break;
  }

  /*
  *   This relies on T_ACI_BS_FRM and T_BAT_framing_format being
  *   identical.
  */
  ilrr_data.framing_format=(T_BAT_framing_format)format;

  /*
  *   This relies on T_ACI_BS_PAR and T_BAT_framing_format being
  *   identical.
  */
  ilrr_data.framing_parity=(T_BAT_framing_parity)parity;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_BUSY            |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_BUSY(
  T_ACI_AT_CMD cmdId,
  SHORT cId)
{
  T_BAT_cmd_response resp;
  T_BAT_no_parameter dummy;  
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;

  TRACE_FUNCTION ("rBAT_BUSY()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  if (src_infos->bat_client[src_infos->active_client].atd_live EQ TRUE)
  {
    /*
    *   We were still waiting for a final response to ATD - this is it.
    */
    resp.ctrl_response=BAT_RES_AT_BUSY;
    src_infos->bat_client[src_infos->active_client].atd_live=FALSE;
  }
  else
  {
    /*
    *   We've already had the final response to ATD, so this must be
    *   an unsolicited message.
    */
    resp.ctrl_response=BAT_RES_UNS_AT_BUSY;
  }

  resp.response.ptr_at_busy = &dummy;
  dummy.bat_dummy = 0xFF;

  aci_bat_send(src_infos,&resp);

  /* check for possible next command queued */
  aci_bat_run_cmd (src_infos); 
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_NO_ANSWER       |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_NO_ANSWER(
  T_ACI_AT_CMD cmdId,
  SHORT cId)
{
  T_BAT_cmd_response resp;
  T_BAT_no_parameter dummy;
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;

  TRACE_FUNCTION ("rBAT_NO_ANSWER()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  if (src_infos->bat_client[src_infos->active_client].atd_live EQ TRUE)
  {
    /*
    *   We were still waiting for a final response to ATD - this is it.
    */
    resp.ctrl_response=BAT_RES_AT_NO_ANSWER;
    src_infos->bat_client[src_infos->active_client].atd_live=FALSE;
  }
  else
  {
    /*
    *   We've already had the final response to ATD, so this must be
    *   an unsolicited message.
    */
    resp.ctrl_response=BAT_RES_UNS_AT_NO_ANSWER;
  }

  resp.response.ptr_at_no_answer = &dummy;
  dummy.bat_dummy = 0xFF;
  
  aci_bat_send(src_infos,&resp);

  /* check for possible next command queued */
  aci_bat_run_cmd (src_infos);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentSIMREM   |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentSIMREM(
  T_ACI_SIMREM_TYPE srType)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_simrem simrem_data;

  TRACE_FUNCTION ("rBAT_PercentSIMREM()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_SIMREM;
  resp.response.ptr_res_percent_simrem=&simrem_data;

  /*
  *   This relies on T_ACI_SIMREM_TYPE being identical to
  *   T_BAT_percent_simrem_m.
  */
  simrem_data.m=(T_BAT_percent_simrem_m)srType;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCLIR        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCLIR(
  T_ACI_CLIR_MOD mode,
  T_ACI_CLIR_STAT stat)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_clir clir_data;

  TRACE_FUNCTION ("rBAT_PlusCLIR()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_QUE_PLUS_CLIR;
  resp.response.ptr_que_plus_clir=&clir_data;

  /*
  *   T_ACI_CLIR_STAT and T_BAT_plus_clir_m are identical except for
  *   the fact that the BAT version does not include a 'not present'
  *   value.
  */
  if (stat==CLIR_STAT_NotPresent)
    clir_data.m=BAT_CLIR_M_UNKNOWN;
  else
    clir_data.m=(T_BAT_plus_clir_m)stat;

  /*
  *   This relies on T_ACI_CLIR_MOD and T_BAT_plus_clir_n being
  *   identical.
  */
  clir_data.n=(T_BAT_plus_clir_n)mode;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCOLR     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCOLR(
  T_ACI_COLR_STAT stat)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_PercentCOLR() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_PercentCOLR() - FAKE");
  rCI_PercentCOLR(stat);

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCSSI        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCSSI(
  T_ACI_CSSI_CODE code,
  SHORT index)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_cssi cssi_data;

  TRACE_FUNCTION ("rBAT_PlusCSSI()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_CSSI;
  resp.response.ptr_res_plus_cssi=&cssi_data;

  /*
  *   This relies on T_ACI_CSSI_CODE being identical to
  *   T_BAT_plus_cssi_code1.
  */
  cssi_data.code1=(T_BAT_plus_cssi_code1)code;

  cssi_data.index=(S32)index;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCSSU        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCSSU(
  T_ACI_CSSU_CODE code,
  SHORT index,
  CHAR *number,
  T_ACI_TOA *type,
  CHAR *subaddr,
  T_ACI_TOS *satype)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_cssu cssu_data;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PlusCSSU()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_CSSU;
  resp.response.ptr_res_plus_cssu=&cssu_data;

  /*
  *   This relies on T_ACI_CSSU_CODE and T_BAT_plus_cssu_code2
  *   being identical.
  */
  cssu_data.code2=(T_BAT_plus_cssu_code2)code;

  cssu_data.index=(S32)index;

  if (number==NULL)
  {
    cssu_data.v_number=FALSE;
  }
  else
  {
    len=strlen(number);

    cssu_data.v_number=TRUE;

    if (len<=BAT_MAX_CSSU_NUMBER_LEN)
    {
      memcpy(cssu_data.number,number,BAT_MAX_CSSU_NUMBER_LEN);
      cssu_data.c_number=(U8)len;
    }
    else
    {
      /*
      *   This is highly unlikely to happen, but if the number is too
      *   big, then put as many digits as will fit in the BAT structure
      *   from the END of the number.
      */
      memcpy(
        cssu_data.number,
        number+(len-BAT_MAX_CSSU_NUMBER_LEN),
        BAT_MAX_CSSU_NUMBER_LEN);

      cssu_data.c_number=(U8)BAT_MAX_CSSU_NUMBER_LEN;
    }
  }

  if (type==NULL)
  {
    cssu_data.type=-1;
  }
  else
  {
    cssu_data.type=(U16)toa_merge(*type);
  }

  if (subaddr==NULL)
  {
    cssu_data.v_subaddr=FALSE;
    cssu_data.satype=-1;
  }
  else
  {
    cssu_data.v_subaddr=TRUE;

    if (satype==NULL)
      cssu_data.satype=-1;
    else
      cssu_data.satype=(S16)tos_merge(*satype);

    len=strlen(subaddr);

    /*
    *   Easiest thing to do is copy as much subaddress data as the
    *   BAT structure can take. The length field will ensure that
    *   there are no problems, and will result in the subaddress
    *   being truncated if it is too long.
    */
    memcpy(cssu_data.subaddr,subaddr,BAT_MAX_SUBADDR_LENGTH);

    if (len>BAT_MAX_SUBADDR_LENGTH)
      cssu_data.c_subaddr=BAT_MAX_SUBADDR_LENGTH;
    else
      cssu_data.c_subaddr=len;
  }

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCUSD        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCUSD(
  T_ACI_CUSD_MOD m,
  T_ACI_USSD_DATA *ussd,
  SHORT dcs)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_cusd cusd_data;

  TRACE_FUNCTION ("rBAT_PlusCUSD()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_CUSD;
  resp.response.ptr_res_plus_cusd=&cusd_data;

  /*
  *   This assumes that T_ACI_CUSD_MOD and
  *   T_BAT_VAL_plus_cusd_m are equivalent.
  */
  cusd_data.m=(T_BAT_VAL_plus_cusd_m)m;

  if (ussd)
  {
    USHORT len;

    utl_ussdDtaToTe(
      ussd->data,
      ussd->len,
      (UBYTE *)cusd_data.str,
      BAT_MAX_USSD_LEN,
      &len,
      (UBYTE)dcs);

    cusd_data.c_str=(U16)len;
    cusd_data.v_str=TRUE;
  }
  else
  {
    cusd_data.v_str=FALSE;
  }

  cusd_data.dcs=(S16)dcs;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCCFC        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCCFC (T_ACI_CCFC_SET* setting)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_plus_ccfc ccfc_data = {0};

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  TRACE_FUNCTION ("rBAT_PlusCCFC()");

  /* fill the BAT response struct */
  resp.ctrl_response = BAT_RES_SET_PLUS_CCFC;
  resp.response.ptr_set_plus_ccfc = &ccfc_data;

  ccfc_data.status = (T_BAT_plus_ccfc_status)setting->clsstat.status;
  ccfc_data.bearer_class = (T_BAT_plus_ccfc_bearer_class)setting->clsstat.class_type;

  if (ccfc_data.c_number = strlen(setting->number))
  {
    ccfc_data.v_number = TRUE;
    memcpy(ccfc_data.number, setting->number, ccfc_data.c_number);
  }

  /* Convert type to string */
  ccfc_data.type = toa_merge(setting->type);
  
  if(ccfc_data.c_subaddr = strlen(setting->subaddr))
  {
    ccfc_data.v_subaddr = TRUE;
    memcpy(ccfc_data.subaddr, setting->subaddr, ccfc_data.c_subaddr);
  }

  /* Convert sattype to string */
  ccfc_data.satype = tos_merge(setting->satype);

  ccfc_data.time = (SHORT)setting->time;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCLCK        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCLCK(
  T_ACI_CLSSTAT *clsStat)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_plus_clck clck_data;

  TRACE_FUNCTION ("rBAT_PlusCLCK()");

  /*
  *   This shouldn't happen, but there's no point carrying on
  *   if it does.
  */
  if (clsStat==NULL)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_SET_PLUS_CLCK;
  resp.response.ptr_set_plus_clck=&clck_data;

  /*
  *   This relies on T_ACI_CLASS being identical to
  *   T_BAT_bearer_class.
  */
  clck_data.bearer_class=(T_BAT_bearer_class)clsStat->class_type;

  /*
  *   This relies on T_ACI_STATUS being identical to
  *   T_BAT_plus_clck_status. It is, except that the BAT does not
  *   have a 'not present' value.
  */
  clck_data.status=(T_BAT_plus_clck_status)clsStat->status;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCIMI        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCIMI(
  CHAR *imsi)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_plus_cimi cimi_data;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PlusCIMI()");

  /*
  *   This shouldn't happen, but there's no point carrying on
  *   if it does.
  */
  if (imsi==NULL)
    return;

  len=strlen(imsi);

  /*
  *   There is also no point carrying on if the BAT structure has
  *   insufficient space to store the whole IMSI.
  */
  if (len>BAT_MAX_CIMI_IMSI_LEN)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_SET_PLUS_CIMI;
  resp.response.ptr_set_plus_cimi=&cimi_data;

  memcpy(cimi_data.imsi,imsi,BAT_MAX_CIMI_IMSI_LEN);
  cimi_data.c_imsi=(U8)len;

  aci_bat_send(src_infos,&resp);
}

#ifdef SIM_TOOLKIT
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentSATI     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentSATI     ( SHORT len, UBYTE* satCmd )
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_sati sati_data = {0};


  TRACE_FUNCTION ("rBAT_PercentSATI()");
  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  /* fill the response struct and call aci_bat_send() */
  resp.ctrl_response = BAT_RES_UNS_PERCENT_SATI;
  resp.response.ptr_res_percent_sati = &sati_data;

  /* Limit copy length to the BAT size */
  if(sati_data.c_satcmd = len)
      memcpy(sati_data.satcmd, satCmd,
             (sati_data.c_satcmd <= BAT_MAX_SATI_SAT_CMD_LEN) ?
             sati_data.c_satcmd : BAT_MAX_SATI_SAT_CMD_LEN);
  
  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentSATE     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentSATE (SHORT len, UBYTE* satCmd)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_percent_sate sate_data = {0};

  TRACE_FUNCTION ("rBAT_PercentSATE()");
  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  /* fill the response struct and call aci_bat_send() */
  resp.ctrl_response = BAT_RES_SET_PERCENT_SATE;
  resp.response.ptr_set_percent_sate = &sate_data;

  /* Limit copy length to the BAT size */
  if(sate_data.c_satrsp = len)
      memcpy(sate_data.satrsp, satCmd,
             (sate_data.c_satrsp <= BAT_MAX_SATE_SAT_RSP_LEN) ?
             sate_data.c_satrsp : BAT_MAX_SATE_SAT_RSP_LEN);
  
  aci_bat_send(src_infos,&resp);
}
#endif /* SIM_TOOLKIT */


/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentIMEI     |
+--------------------------------------------------------------------+

  PURPOSE : response to atd*#06#  query the IMEI
*/

GLOBAL void rBAT_PercentIMEI(T_ACI_IMEI *imei)
{
  T_ACI_CMD_SRC              src_id;
  T_ACI_DTI_PRC_PSI         *src_infos;
  T_BAT_cmd_response         resp;
  T_BAT_res_que_percent_imei rsp_imei;

  TRACE_FUNCTION ("rBAT_PercentIMEI()");

  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response = BAT_RES_QUE_PERCENT_IMEI;
  resp.response.ptr_que_percent_imei = &rsp_imei;

  memcpy(&rsp_imei, imei, sizeof(T_BAT_res_que_percent_imei));

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentKSIR     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentKSIR (T_ACI_KSIR *ksStat)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  
  TRACE_FUNCTION ("rBAT_PercentKSIR()");

  aci_bat_src_info(&src_id,&src_infos);

  utl_cb_percentKSIR ((U8)src_id, ksStat);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCPI      |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCPI(
  SHORT cId,
  T_ACI_CPI_MSG msgType,
  T_ACI_CPI_IBT ibt,
  T_ACI_CPI_TCH tch,
  USHORT cause)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_cpi cpi_data;
  T_ACI_CLCC_CALDESC clist[MAX_CALL_NR];
  UBYTE len;
  SHORT i;

  TRACE_FUNCTION ("rBAT_PercentCPI()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_CPI;
  resp.response.ptr_res_percent_cpi=&cpi_data;

  cpi_data.cid=(U8)cId;

  /*
  *   This relies on T_ACI_CPI_MSG being equivalent to 
  *   T_BAT_percent_cpi_msgtype.
  */
  cpi_data.msgtype=(T_BAT_percent_cpi_msgtype)msgType;

  /*
  *   This relies on T_ACI_CPI_IBT being equivalent to 
  *   T_BAT_percent_cpi_ibt.
  */
  cpi_data.ibt=(T_BAT_percent_cpi_ibt)ibt;

  /*
  *   This relies on T_ACI_CPI_TCH being equivalent to 
  *   T_BAT_percent_cpi_tch.
  */
  cpi_data.tch=(T_BAT_percent_cpi_tch)tch;

  if( (GET_CAUSE_ORIGIN_ENTITY(cause) EQ CC_ORIGINATING_ENTITY  AND 
        GET_CAUSE_DEFBY(cause) EQ DEFBY_STD )
        OR 
       (cause EQ MNCC_CAUSE_REEST_STARTED OR 
        cause EQ MNCC_CAUSE_REEST_FINISHED) )
  {         
     cpi_data.cause=(S32)GET_CAUSE_VALUE(cause);
  }
  else
  {
    cpi_data.cause=(S32) BAT_PARAMETER_NOT_PRESENT;
  }

  /*
  *   Set all the rest of the information to 'not present' as a
  *   default.
  */
  cpi_data.dir=-1;
  cpi_data.mode=-1;
  cpi_data.type=-1;
  cpi_data.v_number=FALSE;
  cpi_data.v_alpha=FALSE;
  cpi_data.line=-1;
  cpi_data.prog_desc = BAT_P_CPI_PROG_DESC_NOT_PRESENT;

  /*
  *   Now try to obtain the rest of the information.
  */
  if (qAT_PercentCLCC(src_id,clist) EQ AT_CMPL)
  {
    for (i=0;i<MAX_CALL_NR;i++)
    {
      T_ACI_CLCC_CALDESC *call;

      /*
      *   Get a pointer to this particular call for convenience.
      */
      call=&clist[i];

      if (call->idx==ACI_NumParmNotPresent)
        break;

      if (call->idx==cId)
      {
        cpi_data.dir=(U8)call->dir;
        cpi_data.mode=(S16)call->mode;

        len=strlen(call->number);

        if (len && (len<=BAT_MAX_CPI_NUMBER_LEN))
        {
          cpi_data.v_number=TRUE;
          memcpy(cpi_data.number,call->number,len);
          cpi_data.c_number=(U8)len;
        }

        if (call->type.ton!=TON_NotPresent)
          cpi_data.type=(S16)toa_merge(call->type);
      
        if (call->alpha.len)
        {
          USHORT len_cvtd_alpha;

#ifdef NO_ASCIIZ
          utl_chsetFromGsm(
            call->alpha.data,
            call->alpha.len,
            cpi_data.alpha,
            BAT_MAX_CPI_ALPHA_LEN,
            &len_cvtd_alpha,
            GSM_ALPHA_Def);
#else
          utl_chsetFromGsm(
            call->alpha,
            0,
            cpi_data.alpha,
            BAT_MAX_CPI_ALPHA_LEN,
            &len_cvtd_alpha,
            GSM_ALPHA_Int);
#endif

          cpi_data.c_alpha=(U8)len_cvtd_alpha;
          cpi_data.v_alpha=TRUE;
        }

        cpi_data.line=(S16)call->class_type;
        cpi_data.prog_desc = (S16)call->prog_desc;

        /*
        *   We have the information, now break out of the for loop.
        */
        break;

      }
    }
  }

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCTYI     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCTYI(
  T_ACI_CTTY_NEG neg,
  T_ACI_CTTY_TRX trx)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_ctyi ctyi_data;

  TRACE_FUNCTION ("rBAT_PercentCTYI()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_CTYI;
  resp.response.ptr_res_percent_ctyi=&ctyi_data;

  /*
  *   This relies on T_ACI_CTTY_NEG and T_BAT_percent_ctyi_neg
  *   being identical.
  */
  ctyi_data.neg=(T_BAT_percent_ctyi_neg)neg;

  /*
  *   The BAT has a 'not present' value but not an 'unknown' value,
  *   vice versa for the ACI.
  */
  if (trx==CTTY_TRX_Unknown)
    ctyi_data.trx=BAT_TRX_NOT_PRESENT;
  else
    ctyi_data.trx=(T_BAT_trx)trx;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCNUM        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCNUM(
  T_ACI_CNUM_MSISDN *msisdn,
  UBYTE num)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_plus_cnum cnum_data;
  UBYTE i;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PlusCNUM()");

  /*
  *   This shouldn't happen, but there's no point carrying on
  *   if it does.
  */
  if (msisdn==NULL)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_SET_PLUS_CNUM;
  resp.response.ptr_set_plus_cnum=&cnum_data;

  /*
  *   This has delivered a list, however the BAT response only
  *   allows for single items. So we must send each one 
  *   individually.
  */
  for (i=0;i<num;i++)
  {
    T_ACI_CNUM_MSISDN *m;

    /*
    *   Get a pointer to this particular item for convenience.
    */
    m=&msisdn[i];

    if (m->vldFlag==TRUE)
    {
      len=strlen(m->alpha);

      if (len)
      {
        USHORT cvtd_len=0;

        cnum_data.v_alpha=TRUE;

        utl_chsetFromGsm(
          m->alpha,
          (USHORT)len,
          (UBYTE *)cnum_data.alpha,
          BAT_MAX_CNUM_ALPHA_LEN,
          &cvtd_len,
          GSM_ALPHA_Int);

        cnum_data.c_alpha=(U8)cvtd_len;
      }
      else
      {
        cnum_data.v_alpha=FALSE;
      }

      len=strlen(m->number);

      if (len<=BAT_MAX_CNUM_NUMBER_LEN)
      {
        memcpy(cnum_data.number,m->number,BAT_MAX_CNUM_NUMBER_LEN);
        cnum_data.c_number=(U8)len;
      }
      else
      {
        /*
        *   This is highly unlikely to happen, but if the number is too
        *   big, then put as many digits as will fit in the BAT structure
        *   from the END of the number.
        */
        memcpy(
          cnum_data.number,
          m->number+(len-BAT_MAX_CNUM_NUMBER_LEN),
        BAT_MAX_CNUM_NUMBER_LEN);

        cnum_data.c_number=(U8)BAT_MAX_CNUM_NUMBER_LEN;
      }

      cnum_data.type=(U8)toa_merge(m->type);

      cnum_data.index=(U8)i;

      /*
      *   Note that we are losing 'speed', 'service' and 'itc'
      *   as they are not in the BAT.
      */
      
      aci_bat_send(src_infos,&resp);
    }
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCPOL        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCPOL(
  SHORT startIdx,
  SHORT lastIdx,
  T_ACI_CPOL_OPDESC *operLst,
  SHORT usdNtry)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;

  TRACE_FUNCTION ("rBAT_PlusCPOL()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  /*
  *   This could be a response to either a query or a test command.
  */
  if (aci_bat_cur_cmd_get(src_infos)==BAT_CMD_TST_PLUS_CPOL)
  {
    T_BAT_res_tst_plus_cpol cpol_data;

    resp.ctrl_response=BAT_RES_TST_PLUS_CPOL;
    resp.response.ptr_tst_plus_cpol=&cpol_data;

    /*
    *   Note that we lose usdNtry, which is not in the BAT (or in
    *   GSM 07.07) but is in the ACI. Whether this will give us
    *   problems is for further study.
    */
    cpol_data.index1=((S16)startIdx EQ ACI_NumParmNotPresent) ? 1 : (S16)startIdx;
    cpol_data.index2=(S16)lastIdx;

    aci_bat_send(src_infos,&resp);
  }
  else if (operLst!=NULL)
  {
    T_BAT_res_que_plus_cpol cpol_data;
    UBYTE i;

    resp.ctrl_response=BAT_RES_QUE_PLUS_CPOL;
    resp.response.ptr_que_plus_cpol=&cpol_data;

    /*
    *   This has delivered a list, however the BAT response only
    *   allows for single items. So we must send each one 
    *   individually.
    */
    for (i=0;i<MAX_OPER;i++)    
    {
      T_ACI_CPOL_OPDESC *o;
      UBYTE len;

      /*
      *   Get a pointer to this particular item for convenience.
      */
      o=&operLst[i];

      /*
      *   Stop when we reach the end of the list.
      */
      if (o->index==ACI_NumParmNotPresent)
        break;

      cpol_data.index=(U8)o->index;

      /*
      *   This relies on T_ACI_CPOL_FRMT and T_BAT_plus_cpol_format
      *   being identical.
      */
      cpol_data.format=(T_BAT_plus_cpol_format)o->format;

      len=strlen(o->oper);

      /*
      *   We copy as much of the operator name as the BAT structure
      *   can handle. If it is too long it will effectively be
      *   truncated.
      */
      if (len>BAT_MAX_CPOL_OPER_LEN)
        cpol_data.c_oper=BAT_MAX_CPOL_OPER_LEN;
      else
        cpol_data.c_oper=(U8)len;

      memcpy(cpol_data.oper,o->oper,BAT_MAX_CPOL_OPER_LEN);

      aci_bat_send(src_infos,&resp);
    }
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCCCM        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCCCM(
  LONG *ccm)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_cccm cccm_data;

  TRACE_FUNCTION ("rBAT_PlusCCCM()");

  /*
  *   This shouldn't happen, but there's no point carrying on
  *   if it does.
  */
  if (ccm==NULL)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_CCCM;
  resp.response.ptr_res_plus_cccm=&cccm_data;

  cccm_data.ccm=(U32)*ccm;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCTV      |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCTV(void)
{
#ifndef FF_ATI_BAT
  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_PercentCTV() - IGNORED");
#else
  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_PercentCTV() - FAKE");
  rCI_PercentCTV();
#endif
}

#ifdef SIM_TOOLKIT
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentSATN     |
+--------------------------------------------------------------------+

  PURPOSE : 
  
  N.B. Not all ACI parameters are supported by BAT
       ACI parameters are SHORT len, UBYTE* satCmd, T_ACI_SATN_CNTRL_TYPE  cntrl_type
*/
GLOBAL void rBAT_PercentSATN (SHORT len, UBYTE* satCmd, T_ACI_SATN_CNTRL_TYPE  cntrl_type)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_satn satn_data = {0};

  TRACE_FUNCTION ("rBAT_PercentSATN()");
  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  /* fill the response struct and call aci_bat_send() */
  resp.ctrl_response = BAT_RES_UNS_PERCENT_SATN;
  resp.response.ptr_res_percent_satn = &satn_data;

  if(satn_data.c_satcmd = len)
      memcpy(satn_data.satcmd, satCmd,
             (satn_data.c_satcmd <= BAT_MAX_SATN_SAT_CMD_LEN) ?
             satn_data.c_satcmd : BAT_MAX_SATN_SAT_CMD_LEN);
  
  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentSATA     |
+--------------------------------------------------------------------+

  PURPOSE : 
  
  N.B. Not all ACI parameters are supported by BAT
       ACI parameters are SHORT cId, LONG rdlTimeout_ms, T_ACI_SATA_ADD* addParm
*/
#ifdef FF_SAT_E
GLOBAL void rBAT_PercentSATA (SHORT cId, LONG rdlTimeout_ms, T_ACI_SATA_ADD* addParm)
#else
GLOBAL void rBAT_PercentSATA (SHORT cId, LONG rdlTimeout_ms)
#endif
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_sata sata_data = {0};

  TRACE_FUNCTION ("rBAT_PercentSATA()");

#ifdef FF_SAT_E
  /* Store for use with rCI_PercentSATA - ATI maintenace 
   * Addparm is a global variable ! */
  memcpy(&Addparm, addParm, sizeof(T_ACI_SATA_ADD));
#endif
  
  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  /* fill the response struct and call aci_bat_send() */
  resp.ctrl_response = BAT_RES_UNS_PERCENT_SATA;
  resp.response.ptr_res_percent_sata = &sata_data;
  sata_data.redial_timeout = (S32)rdlTimeout_ms;
  aci_bat_send(src_infos,&resp);
}
#endif /* SIM_TOOLKIT */

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_sms_ready       |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_sms_ready(void)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_sms_ready() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_sms_ready() - FAKE");
  rCI_sms_ready();

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_phb_status      |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_phb_status(
  T_ACI_PB_STAT status)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_phb_status() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_phb_status() - FAKE");
  rCI_phb_status(status);

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentSIMINS   |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentSIMINS(
  T_ACI_CME_ERR err)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_simins simins_data;

  TRACE_FUNCTION ("rBAT_PercentSIMINS()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_SIMINS;
  resp.response.ptr_res_percent_simins=&simins_data;

  /*
  *   T_ACI_CME_ERR is different from T_BAT_percent_simins_n, so
  *   we need this conversion.
  */
  switch (err)
  {
    case CME_ERR_NotPresent:
      simins_data.n=BAT_P_SIMINS_N_NO_PIN;
      break;

    case CME_ERR_SimPinReq:
      simins_data.n=BAT_P_SIMINS_N_SIM_PIN;
      break;

    case CME_ERR_SimPukReq:
      simins_data.n=BAT_P_SIMINS_N_SIM_PUK;
      break;

    case CME_ERR_SimFail:
      simins_data.n=BAT_P_SIMINS_N_SIM_FAIL;
      break;

    case CME_ERR_SimBusy:
      simins_data.n=BAT_P_SIMINS_N_SIM_BUSY;
      break;

    case CME_ERR_SimWrong:
      simins_data.n=BAT_P_SIMINS_N_SIM_WRONG;
      break;

    default:
      simins_data.n=BAT_P_SIMINS_N_UNKNOWN;
      break;
  }

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCRSM        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCRSM(
  SHORT sw1,
  SHORT sw2,
  SHORT rspLen,
  UBYTE *rsp)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_plus_crsm crsm_data;

  TRACE_FUNCTION ("rBAT_PlusCRSM()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_SET_PLUS_CRSM;
  resp.response.ptr_set_plus_crsm=&crsm_data;

  crsm_data.sw1=(U8)sw1;
  crsm_data.sw2=(U8)sw2;
  
  if (rsp==NULL)
  {
    crsm_data.c_response=0;
  }
  else
  {
    /*
    *   There's nothing meaningful that we can do if there is too
    *   much data to fit in the BAT message, so give up.
    */
    if (rspLen>BAT_MAX_CRSM_RESPONSE_LEN)
      return;

    crsm_data.c_response=(U16)rspLen;
    memcpy(crsm_data.response,rsp,BAT_MAX_CRSM_RESPONSE_LEN);
  }

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCSIM        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCSIM(
  SHORT len,
  UBYTE *rsp)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_set_plus_csim csim_data;

  TRACE_FUNCTION ("rBAT_PlusCSIM()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_SET_PLUS_CSIM;
  resp.response.ptr_set_plus_csim=&csim_data;

  if (rsp==NULL)
  {
    csim_data.c_response=0;
  }
  else
  {
    /*
    *   There's nothing meaningful that we can do if there is too
    *   much data to fit in the BAT message, so give up.
    */
    if (len>BAT_MAX_CSIM_RESP_LEN)
      return;

    csim_data.c_response=(U16)len;
    memcpy(csim_data.response,rsp,BAT_MAX_CSIM_RESP_LEN);
  }

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCCBS     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCCBS(
  T_ACI_CCBS_IND ind,
  T_ACI_CCBS_STAT status,
  T_ACI_CCBS_SET *setting,
  BOOL intermediate_result)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PercentCCBS()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  if (intermediate_result==FALSE)
  {
    T_BAT_res_uns_percent_ccbs ccbs_data;

    resp.ctrl_response=BAT_RES_UNS_PERCENT_CCBS;
    resp.response.ptr_res_percent_ccbs=&ccbs_data;

    /*
    *   This relies on T_ACI_CCBS_IND being identical to T_BAT_percent_ccbs_ind
    *   and T_ACI_CCBS_STAT being identical to T_BAT_percent_ccbs_stat.
    */
    ccbs_data.ind=(T_BAT_percent_ccbs_ind)ind;
    ccbs_data.stat=(T_BAT_percent_ccbs_stat)status;

    /*
    *   As a default, set all the rest of the parameters as 'not present'.
    */
    ccbs_data.idx=BAT_P_CCBS_INDEX_NOT_PRESENT;
    ccbs_data.v_number=FALSE;
    ccbs_data.type=-1;
    ccbs_data.v_number=FALSE;
    ccbs_data.satype=-1;
    ccbs_data.bearer_class=BAT_CLASS_NOT_PRESENT;
    ccbs_data.ptn=BAT_P_CCBS_PATTERN_NOT_PRESENT;

    if (setting!=NULL)
    {
      if (setting->number[0])
      {
        len=strlen(setting->number);

        if (len<=BAT_MAX_CCBS_NUMBER_LEN)
        {
          memcpy(ccbs_data.number,setting->number,BAT_MAX_CCBS_NUMBER_LEN);
          ccbs_data.c_number=(U8)len;
        }
        else
        {
          /*
          *   This is highly unlikely to happen, but if the number is too
          *   big, then put as many digits as will fit in the BAT structure
          *   from the END of the number.
          */
          memcpy(
            ccbs_data.number,
            setting->number+(len-BAT_MAX_CCBS_NUMBER_LEN),
            BAT_MAX_CCBS_NUMBER_LEN);

          ccbs_data.c_number=(U8)BAT_MAX_CCBS_NUMBER_LEN;
        }

        ccbs_data.v_number=TRUE;
        ccbs_data.type=(S16)toa_merge(setting->type);
      }

      if (setting->subaddr[0])
      {
        len=strlen(setting->subaddr);

        /*
        *   If the subaddress is too big to fit in the BAT message, 
        *   just leave it out.
        */
        if (len<=BAT_MAX_SUBADDR_LENGTH)
        {
          memcpy(ccbs_data.subaddr,setting->subaddr,BAT_MAX_SUBADDR_LENGTH);
          ccbs_data.c_subaddr=(U8)len;
          ccbs_data.v_subaddr=TRUE;
          ccbs_data.satype=(S16)tos_merge(setting->satype);
        }
      }

      /*
      *   This relies on T_ACI_CLASS being identical to T_BAT_bearer_class and
      *   T_ACI_ALRT_PATTERN being identical to T_BAT_percent_ccbs_ptn.
      */
      ccbs_data.bearer_class=(T_BAT_bearer_class)setting->class_type;
      ccbs_data.ptn=(T_BAT_percent_ccbs_ptn)setting->alrtPtn;

      /*
      *   This relies on the value presented being equivalent to
      *   T_BAT_percent_ccbs_idx.
      */
      ccbs_data.idx=(T_BAT_percent_ccbs_idx)setting->idx;
    }
  }
  else
  {
    T_BAT_res_que_percent_ccbs ccbs_data;

    resp.ctrl_response=BAT_RES_QUE_PERCENT_CCBS;
    resp.response.ptr_que_percent_ccbs=&ccbs_data;

    /*
    *   This relies on T_ACI_CCBS_IND being identical to T_BAT_percent_ccbs_ind
    *   and T_ACI_CCBS_STAT being identical to T_BAT_percent_ccbs_stat.
    */
    ccbs_data.ind=(T_BAT_percent_ccbs_ind)ind;
    ccbs_data.stat=(T_BAT_percent_ccbs_stat)status;

    /*
    *   As a default, set all the rest of the parameters as 'not present'.
    */
    ccbs_data.idx=BAT_P_CCBS_INDEX_NOT_PRESENT;
    ccbs_data.v_number=FALSE;
    ccbs_data.type=-1;
    ccbs_data.v_number=FALSE;
    ccbs_data.satype=-1;
    ccbs_data.bearer_class=BAT_CLASS_NOT_PRESENT;
    ccbs_data.ptn=BAT_P_CCBS_PATTERN_NOT_PRESENT;

    if (setting!=NULL)
    {
      if (setting->number[0])
      {
        len=strlen(setting->number);

        if (len<=BAT_MAX_CCBS_NUMBER_LEN)
        {
          memcpy(ccbs_data.number,setting->number,BAT_MAX_CCBS_NUMBER_LEN);
          ccbs_data.c_number=(U8)len;
        }
        else
        {
          /*
          *   This is highly unlikely to happen, but if the number is too
          *   big, then put as many digits as will fit in the BAT structure
          *   from the END of the number.
          */
          memcpy(
            ccbs_data.number,
            setting->number+(len-BAT_MAX_CCBS_NUMBER_LEN),
            BAT_MAX_CCBS_NUMBER_LEN);

          ccbs_data.c_number=(U8)BAT_MAX_CCBS_NUMBER_LEN;
        }

        ccbs_data.v_number=TRUE;
        ccbs_data.type=(S16)toa_merge(setting->type);
      }

      if (setting->subaddr[0])
      {
        len=strlen(setting->subaddr);

        /*
        *   If the subaddress is too big to fit in the BAT message, 
        *   just leave it out.
        */
        if (len<=BAT_MAX_SUBADDR_LENGTH)
        {
          memcpy(ccbs_data.subaddr,setting->subaddr,BAT_MAX_SUBADDR_LENGTH);
          ccbs_data.c_subaddr=(U8)len;
          ccbs_data.v_subaddr=TRUE;
          ccbs_data.satype=(S16)tos_merge(setting->satype);
        }
      }

      /*
      *   This relies on T_ACI_CLASS being identical to T_BAT_bearer_class and
      *   T_ACI_ALRT_PATTERN being identical to T_BAT_percent_ccbs_ptn.
      */
      ccbs_data.bearer_class=(T_BAT_bearer_class)setting->class_type;
      ccbs_data.ptn=(T_BAT_percent_ccbs_ptn)setting->alrtPtn;

      /*
      *   This relies on the value presented being equivalent to
      *   T_BAT_percent_ccbs_idx.
      */
      ccbs_data.idx=(T_BAT_percent_ccbs_idx)setting->idx;
    }
  }

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCCWV        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCCWV(
  T_ACI_CCWV_CHRG charging)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_no_parameter dummy;
  
  TRACE_FUNCTION ("rBAT_PlusCCWV()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response = BAT_RES_UNS_PLUS_CCWV;
  resp.response.ptr_plus_ccwv = &dummy;
  dummy.bat_dummy = 0xFF;

  /*
  *   Note that the 'charging' parameter is lost as it is not in
  *   the BAT.
  */

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCNAP     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCNAP(
  T_callingName *NameId,
  T_ACI_CNAP_STATUS status)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_percent_cnap cnap_data;
  T_BAT_res_uns_percent_cnap uns_cnap_data;



  TRACE_FUNCTION ("rBAT_PercentCNAP()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  /*
  *   This could be either an unsolicited event or a response to a 
  *   query. We have no way of knowing which it was, so we assume that
  *   if we have a NameId, it was unsolicited.
  */
  if (NameId==NULL)
  {
    resp.ctrl_response=BAT_RES_QUE_PERCENT_CNAP;
    resp.response.ptr_que_percent_cnap = &cnap_data;

    /*
    *   This relies on T_ACI_CNAP_STATUS being identical to
    *   T_BAT_percent_cnap_status.
    */
    cnap_data.status=(T_BAT_percent_cnap_status)status;
  }
  else
  {
    T_namePresentationAllowed *cnap_name_info;

    resp.ctrl_response=BAT_RES_UNS_PERCENT_CNAP;
    resp.response.ptr_res_percent_cnap = &uns_cnap_data;

    cnap_name_info=NULL;

    if (NameId->v_namePresentationAllowed)
    {
      uns_cnap_data.pres_mode=BAT_P_CNAP_PRES_NAME;
      cnap_name_info=&NameId->namePresentationAllowed;
    }
    else if (NameId->v_presentationRestricted)
    {
      uns_cnap_data.pres_mode=BAT_P_CNAP_PRES_RESTRICTED;
    }
    else if (NameId->v_nameUnavailable)
    {
      uns_cnap_data.pres_mode=BAT_P_CNAP_PRES_NO_NAME;
    }
    else if (NameId->v_namePresentationRestricted)
    {
      uns_cnap_data.pres_mode=BAT_P_CNAP_PRES_NAME_RESTRICTED;
      cnap_name_info=&NameId->namePresentationRestricted;
    }

    /*
    *   As a default, set the rest of the parameters as 'not present'.
    */
    uns_cnap_data.dcs=-1;
    uns_cnap_data.v_name=FALSE;

    if (cnap_name_info)
    {
      if (cnap_name_info->v_dataCodingScheme)
        uns_cnap_data.dcs=(S16)cnap_name_info->dataCodingScheme;

      if ((cnap_name_info->v_nameString) &&
        (cnap_name_info->v_lengthInCharacters))
      {
        uns_cnap_data.v_name=TRUE;

        /*
        *   Copy as much of the data into the BAT message as it can
        *   handle. If it is too long it will effectively be truncated.
        */
        if (cnap_name_info->lengthInCharacters>BAT_MAX_CNAP_NAME_LEN)
          uns_cnap_data.c_name=BAT_MAX_CNAP_NAME_LEN;
        else
          uns_cnap_data.c_name=cnap_name_info->lengthInCharacters;

        memcpy(
          uns_cnap_data.name,
          &cnap_name_info->nameString.b_nameString,
          BAT_MAX_CNAP_NAME_LEN);
      }
    }
  }

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_SignalSMS       |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_SignalSMS(
  UBYTE state)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_SignalSMS() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_SignalSMS() - FAKE");
  rCI_SignalSMS(state);

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCLAN        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCLAN(
  T_ACI_LAN_SUP *CLang)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_clan clan_data;
  CHAR *str;
 
  TRACE_FUNCTION ("rBAT_PlusCLAN()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_QUE_PLUS_CLAN;
  resp.response.ptr_que_plus_clan=&clan_data;

  str=aci_bat_lang_str(CLang);

  if (str==NULL)
    return;

  clan_data.c_code=strlen(str);

  if (clan_data.c_code<=BAT_MAX_CLAN_CODE_LEN)
  {
    memcpy(clan_data.code,str,BAT_MAX_CLAN_CODE_LEN);
    aci_bat_send(src_infos,&resp);
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCLAE        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCLAE(
  T_ACI_LAN_SUP *CLang)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_clae clae_data;
  CHAR *str;

  TRACE_FUNCTION ("rBAT_PlusCLAE()");

  /*
  *   This shouldn't happen, but there's no point carrying on
  *   if it does.
  */
  if (CLang==NULL)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_CLAE;
  resp.response.ptr_res_plus_clae=&clae_data;

  str=aci_bat_lang_str(CLang);

  if (str==NULL)
    return;

  clae_data.c_code=strlen(str);

  if (clae_data.c_code<=BAT_MAX_CLAE_CODE_LEN)
  {
    memcpy(clae_data.code,str,BAT_MAX_CLAE_CODE_LEN);
    aci_bat_send(src_infos,&resp);
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCSQ      |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCSQ(
  UBYTE rssi,
  UBYTE ber,
  UBYTE actlevel)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_csq csq_data;

  TRACE_FUNCTION ("rBAT_PercentCSQ()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_CSQ;
  resp.response.ptr_res_percent_csq=&csq_data;

  csq_data.rssi=(S16)rssi;
  csq_data.ber=(S16)ber;
  csq_data.actlevel=(S16)actlevel;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentALS      |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentALS(
  T_ACI_ALS_MOD ALSmode)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_tst_percent_als als_data;
 
  TRACE_FUNCTION ("rBAT_PercentALS()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_TST_PERCENT_ALS;
  resp.response.ptr_tst_percent_als=&als_data;

  /*
  *   T_ACI_ALS_MOD is not the same as T_BAT_percent_als_mode, so
  *   we need this conversion.
  */
  switch (ALSmode)
  {
    default:
    case ALS_MOD_NOTPRESENT:
      /*
      *   As the only (mandatory) parameter has no value allowed for
      *   in BAT we may as well give up.
      */
      return;
 
    case ALS_MOD_SPEECH:
      als_data.mode=BAT_P_ALS_MOD_SPEECH;
      break;

    case ALS_MOD_AUX_SPEECH:
      als_data.mode=BAT_P_ALS_MOD_AUX_SPEECH;
      break;
  }

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCTZV        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
#ifdef FF_TIMEZONE
GLOBAL void rBAT_PlusCTZV(S32 timezone)
#else
GLOBAL void rBAT_PlusCTZV(UBYTE *timezone)
#endif
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_ctzv ctzv_data;

  TRACE_FUNCTION ("rBAT_PlusCTZV()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_CTZV;
  resp.response.ptr_res_plus_ctzv=&ctzv_data;

#ifdef FF_TIMEZONE
  ctzv_data.tz=(U8)timezone;
#else
  if (timezone==NULL)
    return;
  else
    ctzv_data.tz=(U8)*timezone;
#endif
  
  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCREG     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCREG(
  T_ACI_CREG_STAT status,
  USHORT lac,
  USHORT cid,
  T_ACI_P_CREG_GPRS_IND gprs_ind)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_creg creg_data;

  TRACE_FUNCTION ("rBAT_PercentCREG()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_CREG;
  resp.response.ptr_res_percent_creg=&creg_data;

  /*
  *   This relies on T_ACI_CREG_STAT and T_BAT_percent_creg_stat being
  *   identical.
  */
  creg_data.stat=(T_BAT_percent_creg_stat)status;

  creg_data.lac=(S32)lac;
  creg_data.ci=(S32)cid;

  /*
  *   This relies on T_ACI_P_CREG_GPRS_IND and T_BAT_percent_creg_gprs_ind
  *   being identical.
  */
  creg_data.gprs_ind=(T_BAT_percent_creg_gprs_ind)gprs_ind;

  aci_bat_send(src_infos,&resp);
}

#ifdef GPRS
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCGACT       |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCGACT(
  SHORT link_id)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_PlusCGACT() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_PlusCGACT() - FAKE");
  rCI_PlusCGACT(link_id);

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCGDATA      |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCGDATA(
  SHORT link_id)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_PlusCGDATA() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_PlusCGDATA() - FAKE");
  rCI_PlusCGDATA(link_id);

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCGANS       |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCGANS(
  SHORT link_id)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_PlusCGANS() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_PlusCGANS() - FAKE");
  rCI_PlusCGANS(link_id);

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCGEREP      |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCGEREP(
  T_CGEREP_EVENT event,
  T_CGEREP_EVENT_REP_PARAM *param)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_PlusCGEREP() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_PlusCGEREP() - FAKE");
  rCI_PlusCGEREP(event,param);

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCGREG       |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCGREG(
  T_CGREG_STAT stat,
  USHORT lac,
  USHORT ci)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_plus_cgreg cgreg_data;

  TRACE_FUNCTION ("rBAT_PlusCGREG()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PLUS_CGREG;
  resp.response.ptr_res_plus_cgreg=&cgreg_data;

  /*
  *   This relies on T_CGREG_STAT and T_BAT_plus_cgreg_stat being
  *   identical. They are, except in that the ACI version has a
  *   'not present' value. We deal with it by using 'unknown'.
  */
  if (stat==CGREG_STAT_NOT_PRESENT)
    cgreg_data.stat=BAT_CGREG_STAT_UNKN;
  else
    cgreg_data.stat=(T_BAT_plus_cgreg_stat)stat;

  cgreg_data.lac=(S32)lac;
  cgreg_data.ci=(S32)ci;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_changedQOS      |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_changedQOS(
  SHORT cid,
  T_QOS *qos)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_changedQOS() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_changedQOS() - FAKE");
  rCI_changedQOS(cid,qos);

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentSNCNT    |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentSNCNT(
  UBYTE c_id,
  ULONG octets_uplink,
  ULONG octets_downlink,
  ULONG packets_uplink,
  ULONG packets_downlink)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_sncnt sncnt_data;

  TRACE_FUNCTION ("rBAT_PercentSNCNT()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_SNCNT;
  resp.response.ptr_uns_percent_sncnt=&sncnt_data;

  /*
  *   Warning: this could potentially deliver a value outside
  *   the range specified by BAT.
  */
  sncnt_data.cid=(T_BAT_pdp_cid)c_id;

  sncnt_data.oct_up=(U32)octets_uplink;
  sncnt_data.oct_down=(U32)octets_downlink;
  sncnt_data.pkt_up=(U32)packets_uplink;
  sncnt_data.pkt_down=(U32)packets_downlink;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCGREG    |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCGREG(
  T_P_CGREG_STAT stat,
  USHORT lac,
  USHORT ci,
  BOOL bActiveContext)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_cgreg cgreg_data;

  TRACE_FUNCTION ("rBAT_PercentCGREG()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_CGREG;
  resp.response.ptr_res_percent_cgreg=&cgreg_data;

  /*
  *   This relies on T_P_CGREG_STAT and T_BAT_percent_cgreg_stat being
  *   identical. They are, except in that the ACI version has a
  *   'not present' value. We deal with it by using 'unknown'.
  */
  if (stat==P_CGREG_STAT_NOT_PRESENT)
    cgreg_data.stat=BAT_P_CGREG_STAT_UNKN;
  else
    cgreg_data.stat=(T_BAT_percent_cgreg_stat)stat;

  cgreg_data.lac=(S32)lac;
  cgreg_data.ci=(S32)ci;

  aci_bat_send(src_infos,&resp);
}

#endif /* GPRS */
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentEM       |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentEM(
  T_EM_VAL *val_tmp)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_PercentEM() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_PercentEM() - FAKE");
  rCI_PercentEM(val_tmp);

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentEMET     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentEMET(
  T_DRV_SIGNAL_EM_EVENT *Signal)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_PercentEMET() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_PercentEMET() - FAKE");
  rCI_PercentEMET(Signal);

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentEMETS    |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentEMETS(
  UBYTE entity)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_PercentEMETS() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_PercentEMETS() - FAKE");
  rCI_PercentEMETS(entity);

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCPNUMS   |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCPNUMS(
  UBYTE element_index,
  UBYTE index_level,
  CHAR *alpha_tag,
  CHAR *number,
  BOOL premium_flag,
  BOOL network_flag)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  UBYTE len;

  TRACE_FUNCTION ("rBAT_PercentCPNUMS()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  /*
  *   This is either a response to a test or a set command.
  */
  if (aci_bat_cur_cmd_get(src_infos)==BAT_CMD_TST_PERCENT_CPNUMS)
  {
    T_BAT_res_tst_percent_cpnums cpnums_data;

    resp.ctrl_response=BAT_RES_TST_PERCENT_CPNUMS;
    resp.response.ptr_tst_percent_cpnums=&cpnums_data;

    cpnums_data.element_id=(U8)element_index;
    cpnums_data.index_level=(U8)index_level;

    cpnums_data.c_alpha_tag=0;

    if (alpha_tag NEQ NULL)
    {
      len=strlen(alpha_tag);

      if (len)
      {
        USHORT len_cvtd_text=0;

        /*
        *   Convert the data read from the SIM into the currently 
        *   selected character set.
        */
        utl_chsetFromSim(
          (UBYTE *)alpha_tag,
          (USHORT)len,
          (UBYTE *)cpnums_data.alpha_tag,
          BAT_MAX_CPNUMS_ALPHA_TAG_LEN,
          &len_cvtd_text,
          GSM_ALPHA_Def);

        cpnums_data.c_alpha_tag=(U8)len_cvtd_text;
      }
    }

    if (number==NULL)
    {
      cpnums_data.c_number=0;
      cpnums_data.number[0]=0;
    }
    else
    {
      len=strlen(number);

      if (len<=BAT_MAX_CPNUMS_NUMBER_LEN)
      {
        memcpy(cpnums_data.number,number,BAT_MAX_CPNUMS_NUMBER_LEN);
        cpnums_data.c_number=(U8)len;
      }
      else
      {
        /*
        *   This is highly unlikely to happen, but if the number is too
        *   big, then put as many digits as will fit in the BAT structure
        *   from the END of the number.
        */
        memcpy(
          cpnums_data.number,
          number+(len-BAT_MAX_CPNUMS_NUMBER_LEN),
          BAT_MAX_CPNUMS_NUMBER_LEN);

        cpnums_data.c_number=(U8)BAT_MAX_CPNUMS_NUMBER_LEN;
      }
    }

    cpnums_data.premium_flag=(premium_flag==TRUE) ?
      BAT_P_CPNUMS_PREMIUM_FLAG_SET:BAT_P_CPNUMS_PREMIUM_FLAG_NOT_SET;

    cpnums_data.network_flag=(network_flag==TRUE) ?
      BAT_P_CPNUMS_NETWORK_SET:BAT_P_CPNUMS_NETWORK_NOT_SET;

    aci_bat_send(src_infos,&resp);
  }
  else
  {
    T_BAT_res_set_percent_cpnums cpnums_data;

    resp.ctrl_response=BAT_RES_SET_PERCENT_CPNUMS;
    resp.response.ptr_set_percent_cpnums=&cpnums_data;

    cpnums_data.element_id=(U8)element_index;
    cpnums_data.index_level=(U8)index_level;

    cpnums_data.c_alpha_tag=0;

    if (alpha_tag NEQ NULL)
    {
      len=strlen(alpha_tag);

      if (len)
      {
        USHORT len_cvtd_text=0;

        /*
        *   Convert the data read from the SIM into the currently 
        *   selected character set.
        */
        utl_chsetFromSim(
          (UBYTE *)alpha_tag,
          (USHORT)len,
          (UBYTE *)cpnums_data.alpha_tag,
          BAT_MAX_CPNUMS_ALPHA_TAG_LEN,
          &len_cvtd_text,
          GSM_ALPHA_Def);

        cpnums_data.c_alpha_tag=(U8)len_cvtd_text;
      }
    }

    if (number==NULL)
    {
      cpnums_data.c_number=0;
      cpnums_data.number[0]=0;
    }
    else
    {
      len=strlen(number);

      if (len<=BAT_MAX_CPNUMS_NUMBER_LEN)
      {
        memcpy(cpnums_data.number,number,BAT_MAX_CPNUMS_NUMBER_LEN);
        cpnums_data.c_number=(U8)len;
      }
      else
      {
        /*
        *   This is highly unlikely to happen, but if the number is too
        *   big, then put as many digits as will fit in the BAT structure
        *   from the END of the number.
        */
        memcpy(
          cpnums_data.number,
          number+(len-BAT_MAX_CPNUMS_NUMBER_LEN),
          BAT_MAX_CPNUMS_NUMBER_LEN);

        cpnums_data.c_number=(U8)BAT_MAX_CPNUMS_NUMBER_LEN;
      }
    }

    cpnums_data.premium_flag=(premium_flag==TRUE) ?
      BAT_P_CPNUMS_PREMIUM_FLAG_SET:BAT_P_CPNUMS_PREMIUM_FLAG_NOT_SET;

    cpnums_data.network_flag=(network_flag==TRUE) ?
      BAT_P_CPNUMS_NETWORK_SET:BAT_P_CPNUMS_NETWORK_NOT_SET;

    aci_bat_send(src_infos,&resp);
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCPVWI    |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCPVWI(
  UBYTE flag_set, 
  USHORT line)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;

  TRACE_FUNCTION ("rBAT_PercentCPVWI()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  /*
  *   This could be either a response to a set command, or an 
  *   unsolicited event.
  */
  if (aci_bat_cur_cmd_get(src_infos)!=BAT_CMD_SET_PERCENT_CPVWI)
  {
    T_BAT_res_uns_percent_cpvwi cpvwi_data;

    resp.ctrl_response=BAT_RES_UNS_PERCENT_CPVWI;
    resp.response.ptr_res_percent_cpvwi=&cpvwi_data;

    cpvwi_data.line=(T_BAT_percent_cpvwi_lines)line;

    cpvwi_data.status=(flag_set==TRUE) ?
      BAT_P_CPVWI_FLAG_ACTIVATED:BAT_P_CPVWI_FLAG_DEACTIVATED;

    aci_bat_send(src_infos,&resp);
  }
  else
  {
    T_BAT_res_set_percent_cpvwi cpvwi_data;

    resp.ctrl_response=BAT_RES_SET_PERCENT_CPVWI;
    resp.response.ptr_set_percent_cpvwi=&cpvwi_data;

    cpvwi_data.line=(T_BAT_percent_cpvwi_lines)line;

    cpvwi_data.status=(flag_set==TRUE) ?
      BAT_P_CPVWI_FLAG_ACTIVATED:BAT_P_CPVWI_FLAG_DEACTIVATED;

    aci_bat_send(src_infos,&resp);
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCPROAM   |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCPROAM(
  UBYTE roam_status)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_cproam cproam_data;

  TRACE_FUNCTION ("rBAT_PercentCPROAM()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_CPROAM;
  resp.response.ptr_res_percent_cproam=&cproam_data;

  cproam_data.roam_status=(roam_status) ?
    BAT_P_CPROAM_STATUS_ROAMING:BAT_P_CPROAM_STATUS_NOT_ROAMING;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusCIEV        |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PlusCIEV(
  T_ACI_MM_CIND_VAL_TYPE sCindValues,
  T_ACI_MM_CMER_VAL_TYPE sCmerSettings)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_PlusCIEV() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_PlusCIEV() - FAKE");
  rCI_PlusCIEV(sCindValues,sCmerSettings);

#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentRDL      |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentRDL(
  T_ACI_CC_REDIAL_STATE state)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_rdl rdl_data;

  TRACE_FUNCTION ("rBAT_PercentRDL()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_RDL;
  resp.response.ptr_res_percent_rdl=&rdl_data;

  /*
  *   This relies on T_ACI_CC_REDIAL_STATE being identical to
  *   T_BAT_percent_rdl_state.
  */
  rdl_data.state=(T_BAT_percent_rdl_state)state;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentRDLB     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentRDLB(
  T_ACI_CC_RDL_BLACKL_STATE state)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_rdlb rdlb_data;

  TRACE_FUNCTION ("rBAT_PercentRDLB()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_RDLB;
  resp.response.ptr_res_percent_rdlb=&rdlb_data;

  /*
  *   This relies on T_ACI_CC_RDL_BLACKL_STATE being identical to
  *   T_BAT_percent_rdlb_state.
  */
  rdlb_data.state=(T_BAT_percent_rdlb_state)state;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCCCN     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCCCN(
  T_ACI_FAC_DIR tDirection,
  SHORT cId,
  T_fac_inf *fie)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_cccn cccn_data;

  TRACE_FUNCTION ("rBAT_PercentCCCN()");

  /*
  *   No point continuing if we don't have this.
  */
  if (fie==NULL)
    return;

  /*
  *   There's also no point continuing if the facility information
  *   can't fit into the BAT message.
  */
  if (fie->l_fac>BAT_MAX_CCCN_FACILITY_LEN)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_CCCN;
  resp.response.ptr_res_percent_cccn=&cccn_data;

  /*
  *   This relies on T_ACI_FAC_DIR and T_BAT_percent_cccn_direction
  *   being identical. They are, except that the ACI has a 'not
  *   present' value.
  */
  cccn_data.direction=(T_BAT_percent_cccn_direction)tDirection;

  cccn_data.cid=(U16)cId;

  /*
  *   Copy the facility data, secure in the knowledge that we have
  *   enough room for it.
  */
  memcpy(cccn_data.facility,fie->fac,BAT_MAX_CCCN_FACILITY_LEN);
  cccn_data.c_facility=(U8)fie->l_fac;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCSSN     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCSSN(
  T_ACI_FAC_DIR tDirection,
  T_ACI_FAC_TRANS_TYPE tType,
  T_fac_inf *fie)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_cssn cssn_data;

  TRACE_FUNCTION ("rBAT_PercentCSSN()");

  /*
  *   No point continuing if we don't have this.
  */
  if (fie==NULL)
    return;

  /*
  *   There's also no point continuing if the facility information
  *   can't fit into the BAT message.
  */
  if (fie->l_fac>BAT_MAX_CSSN_FACILITY_LEN)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_CSSN;
  resp.response.ptr_res_percent_cssn=&cssn_data;

  /*
  *   This relies on T_ACI_FAC_DIR being the same as
  *   T_BAT_percent_cssn_direction, and T_ACI_FAC_TRANS_TYPE being the
  *   same as T_BAT_percent_cssn_trans_type. They are, except that
  *   T_ACI_FAC_DIR also has a 'not present' value.
  */
  cssn_data.direction=(T_BAT_percent_cssn_direction)tDirection;
  cssn_data.trans_type=(T_BAT_percent_cssn_trans_type)tType;

  /*
  *   Copy the facility data, secure in the knowledge that we have
  *   enough room for it.
  */
  memcpy(cssn_data.facility,fie->fac,BAT_MAX_CSSN_FACILITY_LEN);
  cssn_data.c_facility=(U8)fie->l_fac;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCSTAT    |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCSTAT(
  T_ACI_STATE_MSG msgType)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_cstat cstat_data;

  TRACE_FUNCTION ("rBAT_PercentCSTAT()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_CSTAT;
  resp.response.ptr_res_percent_cstat=&cstat_data;

  /*
  *   This relies on T_ACI_ENTITY_ID_MSG being the same as
  *   T_BAT_percent_cstat_entity_id and T_ACI_ENTITY_STATE_MSG being
  *   the same as T_BAT_percent_cstat_status.
  */
  cstat_data.entity_id=(T_BAT_percent_cstat_entity_id)msgType.entityId;
  cstat_data.status=(T_BAT_percent_cstat_status)msgType.entityState;
  
  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_Z               |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_Z(void)
{

#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_Z() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_Z() - FAKE");
  rCI_Z();

#endif

}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCPRSM    |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCPRSM(
  T_ACI_CPRSM_MOD mode)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_percent_cprsm cprsm_data;

  TRACE_FUNCTION ("rBAT_PercentCPRSM()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_QUE_PERCENT_CPRSM;
  resp.response.ptr_que_percent_cprsm=&cprsm_data;

  /*
  *   This relies on T_ACI_CPRSM_MOD and T_BAT_percent_cprsm_mode being
  *   identical. They are, except that the ACI version includes a
  *   'not present' value.
  */
  cprsm_data.mode=(T_BAT_percent_cprsm_mode)mode;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCTZV     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCTZV(
  T_MMR_INFO_IND *mmr_info_ind,
  S32 timezone)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_ctzv ctzv_data;
 
  TRACE_FUNCTION ("rBAT_PercentCTZV()");

  if (mmr_info_ind==NULL)
    return;

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_CTZV;
  resp.response.ptr_res_percent_ctzv=&ctzv_data;

  if ((mmr_info_ind->plmn.v_plmn) &&
    ((SIZE_MCC+SIZE_MNC) <= BAT_MAX_CTZV_NUM_OPER_LEN))
  {
    ctzv_data.v_num_oper=TRUE;
    memcpy(ctzv_data.num_oper,mmr_info_ind->plmn.mcc,SIZE_MCC);
    memcpy(ctzv_data.num_oper+SIZE_MCC,mmr_info_ind->plmn.mnc,SIZE_MNC);
    ctzv_data.c_num_oper=(U8)(SIZE_MCC+SIZE_MNC);
  }
  else
  {
    ctzv_data.v_num_oper=FALSE;
  }

  if (mmr_info_ind->short_name.v_name)
  {
    USHORT len;

    utl_chsetFromGsm(
      mmr_info_ind->short_name.text,
      mmr_info_ind->short_name.c_text,
      ctzv_data.short_oper,
      BAT_MAX_CTZV_SHORT_OPER,
      &len,
      GSM_ALPHA_Def);

    ctzv_data.v_short_oper=TRUE;
    ctzv_data.c_short_oper=(U8)len;

    /* Extend BAT to included add_ci parameter */
    ctzv_data.add_ci = mmr_info_ind->short_name.add_ci;
  }
  else
  {
    ctzv_data.v_short_oper=FALSE;
  }

  if (mmr_info_ind->full_name.v_name)
  {
    USHORT len;

    utl_chsetFromGsm(
      mmr_info_ind->full_name.text,
      mmr_info_ind->full_name.c_text,
      ctzv_data.long_oper,
      BAT_MAX_CTZV_LONG_OPER,
      &len,
      GSM_ALPHA_Def);

    ctzv_data.v_long_oper=TRUE;
    ctzv_data.c_long_oper=(U8)len;
     
    /* Extend BAT to included add_ci parameter */
    ctzv_data.add_ci = mmr_info_ind->full_name.add_ci;
  }
  else
  {
    ctzv_data.v_long_oper=FALSE;
  }
  
  ctzv_data.year=(U8)mmr_info_ind->time.year;
  ctzv_data.month=(U8)mmr_info_ind->time.month;
  ctzv_data.day=(U8)mmr_info_ind->time.day;
  ctzv_data.hour=(U8)mmr_info_ind->time.hour;
  ctzv_data.minutes=(U8)mmr_info_ind->time.minute;
  ctzv_data.seconds=(U8)mmr_info_ind->time.second;
  ctzv_data.time_zone=(S8)timezone;

  aci_bat_send(src_infos,&resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCNIV     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCNIV(
  T_MMR_INFO_IND *mmr_info_ind)
{
#ifndef FF_ATI_BAT

  /*
  *   This is not included in the BAT interface, so ignore it.
  */
  TRACE_FUNCTION ("rBAT_PercentCNIV() - IGNORED");

#else

  /*
  *   But for test purposes, fake a response by calling the equivalent
  *   ATI function directly.
  */
  TRACE_FUNCTION ("rBAT_PercentCNIV() - FAKE");
  rCI_PercentCNIV(mmr_info_ind);

#endif
}

#ifdef GPRS
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCGEV     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCGEV (T_CGEREP_EVENT event, T_CGEREP_EVENT_REP_PARAM *param)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_cgev cgev_data;
  U8 len;

  TRACE_FUNCTION ("rBAT_PercentCGEV()");

  if (event==CGEREP_EVENT_INVALID)
  {
    return;
  }
  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

#ifdef _SIMULATION_
  if (ati_user_output_cfg[src_id].Percent_CGEREP_stat == 0)
  {
    return; /* don't indicate %CGEV to a source on which AT%CGEREP was not set up */
  }
#endif

  resp.ctrl_response=BAT_RES_UNS_PERCENT_CGEV;
  resp.response.ptr_res_percent_cgev=&cgev_data;

  /*
  *   This relies on T_CGEREP_EVENT being identical to
  *   T_BAT_percent_cgev_evt, which it is apart from the additional
  *   'invalid' value in the ACI which we dealt with earlier.
  */
  cgev_data.evt=(T_BAT_percent_cgev_evt)event;

  cgev_data.pdp_type=BAT_PDP_TYPE_NOT_PRESENT;
  cgev_data.v_pdp_addr=FALSE;
  cgev_data.cid=BAT_PDP_CID_NOT_PRESENT;
  cgev_data.p_mobile_class=BAT_P_MOBILE_CLASS_NOT_PRESENT;

  if (param!=NULL)
  {
    switch (event)
    {
      case CGEREP_EVENT_REJECT:
        len=strlen(param->reject.pdp_addr);

        if ((len>0) && (len<=BAT_MAX_PDP_ADD))
        {
          cgev_data.pdp_type=BAT_PDP_TYPE_IPV4;
          cgev_data.v_pdp_addr=TRUE;
          cgev_data.c_pdp_addr=(U8)len;
          memcpy(cgev_data.pdp_addr,param->reject.pdp_addr,len);
        }
        break;

      case CGEREP_EVENT_NW_CLASS:
      case CGEREP_EVENT_ME_CLASS:
        /*
        *   This relies on T_PERCENT_CGCLASS being identical to
        *   T_BAT_p_mobile_class.
        */
        cgev_data.p_mobile_class=(T_BAT_p_mobile_class)param->mobile_class;
        break;

      case CGEREP_EVENT_NW_REACT:
      case CGEREP_EVENT_NW_DEACT:
      case CGEREP_EVENT_ME_DEACT:
      case CGEREP_EVENT_NW_ACT:
      case CGEREP_EVENT_ME_ACT:
        len=strlen(param->act.pdp_addr);

        if ((len>0) && (len<=BAT_MAX_PDP_ADD))
        {
          cgev_data.pdp_type=BAT_PDP_TYPE_IPV4;

          cgev_data.v_pdp_addr=TRUE;
          cgev_data.c_pdp_addr=(U8)len;
          memcpy(cgev_data.pdp_addr,param->act.pdp_addr,len);
        }

        cgev_data.cid=(T_BAT_pdp_cid)param->act.cid;
        break;

      default:
        break;
    }
  }

  aci_bat_send(src_infos,&resp);
}
#endif /* GPRS */

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentCPRI     |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentCPRI(
  UBYTE gsm_ciph,
  UBYTE gprs_ciph)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_cpri cpri_data;
 
  TRACE_FUNCTION ("rBAT_PercentCPRI()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_CPRI;
  resp.response.ptr_res_percent_cpri=&cpri_data;

  cpri_data.gsm_ciph=(T_BAT_percent_cpri_gsm_ciph)gsm_ciph;
  cpri_data.gprs_ciph=(T_BAT_percent_cpri_gprs_ciph)gprs_ciph;

  aci_bat_send(src_infos,&resp);
}



#ifdef FF_FAX
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFIS         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFIS( T_ACI_F_VR vr,
                          T_ACI_F_BR br,
                          T_ACI_F_WD wd,
                          T_ACI_F_LN ln,
                          T_ACI_F_DF df,
                          T_ACI_F_EC ec,
                          T_ACI_F_BF bf,
                          T_ACI_F_ST st,
                          T_ACI_F_JP jp) 
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fis fis;

  TRACE_FUNCTION ("rBAT_PlusFIS()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FIS;
  resp.response.ptr_que_plus_fis = &fis;

  fis.vr = vr;
  fis.br = br;
  fis.wd = wd;
  fis.ln = ln;
  fis.df = df;
  fis.ec = ec;
  fis.bf = bf;
  fis.st = st;
  fis.jp = jp;

  aci_bat_send(src_infos, &resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFCS         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFCS( T_ACI_F_VR vr,
                          T_ACI_F_BR br,
                          T_ACI_F_WD wd,
                          T_ACI_F_LN ln,
                          T_ACI_F_DF df,
                          T_ACI_F_EC ec,
                          T_ACI_F_BF bf,
                          T_ACI_F_ST st,
                          T_ACI_F_JP jp) 
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fcs fcs;

  TRACE_FUNCTION ("rBAT_PlusFCS()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FCS;
  resp.response.ptr_que_plus_fcs = &fcs;

  fcs.vr = vr;
  fcs.br = br;
  fcs.wd = wd;
  fcs.ln = ln;
  fcs.df = df;
  fcs.ec = ec;
  fcs.bf = bf;
  fcs.st = st;
  fcs.jp = jp;

  aci_bat_send(src_infos, &resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFSA         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFSA(U8 c_sub_str, U8 *sub_str)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fsa fsa;

  TRACE_FUNCTION ("rBAT_PlusFSA()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FSA;
  resp.response.ptr_que_plus_fsa = &fsa;
  fsa.c_sub_str = c_sub_str;
  memcpy(fsa.sub_str, sub_str, c_sub_str);

  aci_bat_send(src_infos, &resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFPA         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFPA(U8 c_spa_str, U8 *spa_str)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fpa fpa;

  TRACE_FUNCTION ("rBAT_PlusFPA()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FPA;
  resp.response.ptr_que_plus_fpa = &fpa;
  fpa.c_spa_str = c_spa_str;
  memcpy(fpa.spa_str, spa_str, c_spa_str);

  aci_bat_send(src_infos, &resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFPW         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFPW(U8 c_pw_str, U8 *pw_str)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fpw fpw;

  TRACE_FUNCTION ("rBAT_PlusFPW()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FPW;
  resp.response.ptr_que_plus_fpw = &fpw;
  fpw.c_pw_str = c_pw_str;
  memcpy(fpw.pw_str, pw_str, c_pw_str);

  aci_bat_send(src_infos, &resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFPI         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFPI(U8 c_id_str, U8 *id_str)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fpi fpi;

  TRACE_FUNCTION ("rBAT_PlusFPI()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FPI;
  resp.response.ptr_que_plus_fpi = &fpi;
  fpi.c_id_str = c_id_str;
  memcpy(fpi.id_str, id_str, c_id_str);

  aci_bat_send(src_infos, &resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFNS         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFNS(U8 c_nsf, U8 *nsf)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fns fns;

  TRACE_FUNCTION ("rBAT_PlusFNS()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FNS;
  resp.response.ptr_que_plus_fns = &fns;
  fns.c_nsf = c_nsf;
  memcpy(fns.nsf, nsf, c_nsf);

  aci_bat_send(src_infos, &resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFHS         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFHS(T_BAT_plus_fhs_status status)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fhs fhs;

  TRACE_FUNCTION ("rBAT_PlusFHS()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FHS;
  resp.response.ptr_que_plus_fhs = &fhs;
  fhs.status = status;

  aci_bat_send(src_infos, &resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFPS         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFPS(T_BAT_plus_fps_ppr ppr)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fps fps;

  TRACE_FUNCTION ("rBAT_PlusFPS()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FPS;
  resp.response.ptr_que_plus_fps = &fps;
  fps.ppr = ppr;

  aci_bat_send(src_infos, &resp);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFCO         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFCO(void)
{
/*
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fco fco;

  TRACE_FUNCTION ("rBAT_PlusFCO()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FCO;
  resp.response.ptr_que_plus_fco = &fco;

  aci_bat_send(src_infos, &resp);
*/
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFTI         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFTI(CHAR *tsi)
{
/*
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fti fti;

  TRACE_FUNCTION ("rBAT_PlusFTI()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FTI;
  resp.response.ptr_que_plus_fti = &fti;

  aci_bat_send(src_infos, &resp);
*/
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFCI         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFCI(CHAR *rmtId)
{
/*
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fci fci;

  TRACE_FUNCTION ("rBAT_PlusFCI()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FCI;
  resp.response.ptr_que_plus_fci = &fci;

  aci_bat_send(src_infos, &resp);
*/
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFHT         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFHT(U16 len, U8 *hdlc)
{
/*
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fht fht;

  TRACE_FUNCTION ("rBAT_PlusFHT()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FHT;
  resp.response.ptr_que_plus_fht = &fht;

  aci_bat_send(src_infos, &resp);
*/
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFHR         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFHR(U16 len, U8 *hdlc)
{
/*
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fhr fhr;

  TRACE_FUNCTION ("rBAT_PlusFHR()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FHR;
  resp.response.ptr_que_plus_fhr = &fhr;

  aci_bat_send(src_infos, &resp);
*/
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFET         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFET(T_ACI_FET_PPM ppm)
{
/*
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fet fet;

  TRACE_FUNCTION ("rBAT_PlusFET()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FET;
  resp.response.ptr_que_plus_fet = &fet;

  aci_bat_send(src_infos, &resp);
*/
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFVO         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFVO(void)
{
/*
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fvo fvo;

  TRACE_FUNCTION ("rBAT_PlusFVO()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FVO;
  resp.response.ptr_que_plus_fvo = &fvo;

  aci_bat_send(src_infos, &resp);
*/
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFPO         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFPO(void)
{
/*
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fpo fpo;

  TRACE_FUNCTION ("rBAT_PlusFPO()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FPO;
  resp.response.ptr_que_plus_fpo = &fpo;

  aci_bat_send(src_infos, &resp);
*/
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFNF         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFNF(U16 len, U8 *nsf)
{
/*
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fnf fnf;

  TRACE_FUNCTION ("rBAT_PlusFNF()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FNF;
  resp.response.ptr_que_plus_fnf = &fnf;

  aci_bat_send(src_infos, &resp);
*/
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFNC         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFNC(U16 len, U8 *nsc)
{
/*
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_fnc fnc;

  TRACE_FUNCTION ("rBAT_PlusFNC()");
 
  aci_bat_src_info(&src_id, &src_infos);

  resp.ctrl_response = BAT_RES_QUE_PLUS_FNC;
  resp.response.ptr_que_plus_fnc = &fnc;

  aci_bat_send(src_infos, &resp);
*/
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PlusFTC         |
+--------------------------------------------------------------------+

  PURPOSE : ITU-T.32
*/
GLOBAL void rBAT_PlusFTC( T_ACI_F_VR vr,
                          T_ACI_F_BR br,
                          T_ACI_F_WD wd,
                          T_ACI_F_LN ln,
                          T_ACI_F_DF df,
                          T_ACI_F_EC ec,
                          T_ACI_F_BF bf,
                          T_ACI_F_ST st,
                          T_ACI_F_JP jp) 
{
/*
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_que_plus_ftc ftc;

  TRACE_FUNCTION ("rBAT_PlusFTC()");

  aci_bat_src_info(&src_id, &src_infos);
 
  resp.ctrl_response = BAT_RES_QUE_PLUS_FTC;
  resp.response.ptr_que_plus_ftc = &ftc;

  aci_bat_send(src_infos, &resp);
*/
}

#endif  /* FF_FAX */

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-F&D (8411)            MODULE  : ACI_BAT              |
| STATE   : code                      ROUTINE : rBAT_PercentSIMEF    |
+--------------------------------------------------------------------+

  PURPOSE : 
*/
GLOBAL void rBAT_PercentSIMEF(
  SHORT *ef,
  UBYTE count)
{
  T_ACI_CMD_SRC src_id;
  T_ACI_DTI_PRC_PSI *src_infos;
  T_BAT_cmd_response resp;
  T_BAT_res_uns_percent_simef simef_data;
  UBYTE n;
 
  TRACE_FUNCTION ("rBAT_PercentSIMEF()");

  /*
  *   Get the source ID and a pointer to the PSI source information.
  */
  aci_bat_src_info(&src_id,&src_infos);

  resp.ctrl_response=BAT_RES_UNS_PERCENT_SIMEF;
  resp.response.ptr_res_percent_simef=&simef_data;

  /*
  *   Copy the data in. Note that any excess data will be lost, however
  *   this should not happen as the BAT message has been designed to
  *   carry the entire contents of the T_SIM_FILE_UPDATE_IND primitive.
  */
  for (n=0;((n<count) && (n<BAT_MAX_SIMEF_EF_LEN));n++)
  {
    simef_data.ef[n]=(U16)ef[n];
  }

  simef_data.c_ef=(U8)n;

  aci_bat_send(src_infos,&resp);
}

