diff src/aci2/aci/cmh_lcs.c @ 3:93999a60b835

src/aci2, src/condat2: import of g23m/condat source pieces from TCS211
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 26 Sep 2016 00:29:36 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/aci2/aci/cmh_lcs.c	Mon Sep 26 00:29:36 2016 +0000
@@ -0,0 +1,1330 @@
+/*
++-----------------------------------------------------------------------------
+|  Project :  GSM-PS (6147)
+|  Modul   :  CMH_LCS
++-----------------------------------------------------------------------------
+|  Copyright 2002 Texas Instruments Berlin, AG
+|                 All rights reserved.
+|
+|                 This file is confidential and a trade secret of Texas
+|                 Instruments Berlin, AG
+|                 The receipt of or possession of this file does not convey
+|                 any rights to reproduce or disclose its contents or to
+|                 manufacture, use, or sell anything it may describe, in
+|                 whole, or in part, without the specific written consent of
+|                 Texas Instruments Berlin, AG.
++-----------------------------------------------------------------------------
+|  Purpose :  This module provides the set functions related to the
+|             protocol stack adapter for the location service.
++-----------------------------------------------------------------------------
+*/
+
+#ifndef CMH_LCS_C
+#define CMH_LCS_C
+#endif
+
+#ifdef FF_EOTD
+
+#ifdef MFW
+#define ENTITY_MFW
+#else
+#ifdef SMI
+#define ENTITY_SMI
+#else
+#define ENTITY_ACI
+#endif
+#endif
+
+#define ACI_MEMBER
+
+/*==== INCLUDES ===================================================*/
+#include "aci_all.h"
+#include "aci_cmh.h"
+#include "ati_cmd.h"
+#include "aci_cmd.h"
+
+#include "aci_mem.h"
+#include "psa.h"
+#include "cmh.h"
+#include "psa_util.h"
+
+#if defined(_TMS470)
+#include "ffs/ffs.h"
+#include "ffs_coat.h"
+#endif
+
+#include "aci.h"
+#include "aci_lst.h"
+#include "cmh_lc.h"
+/* needed for CPS test */
+#include "l4_tim.h"
+/*==== CONSTANTS ==================================================*/
+#define MAX_LC_CALLREF   5
+#define CLPS_DEF_PER_UP_VALUE 0x000f
+/*==== EXPORT =====================================================*/
+EXTERN CHAR  *parse(CHAR *b,CHAR *f, ...);
+EXTERN T_ACI_LIST    *ati_src_list;
+
+#if defined(_TMS470)
+EXTERN UBYTE search_tim_handl(void);
+EXTERN U8 lc_cps_traces;
+EXTERN U32 lc_msmsnr;
+#endif
+/*==== VARIABLES ==================================================*/
+/*==== FUNCTIONS ==================================================*/
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_LCS                                       |
+|                                 ROUTINE : lc_callref_init                                                  |
++-------------------------------------------------------------------+
+
+  PURPOSE : search callreference for location service request
+*/
+GLOBAL UBYTE lc_callref_init (void)
+{
+  int   i;
+  UBYTE tst_id;
+
+  for (i = 0; i <= MAX_LC_CALLREF; i++)
+  {
+    tst_id = (0x01 << i) & used_lc_callref;
+    if (!tst_id)
+      break;
+  }
+  if (tst_id)
+    return (0);
+  used_lc_callref |= (0x01 << i);
+  return (i);
+}
+
+#if defined(_TMS470)
+LOCAL const char* lc_client_list[]=
+{
+  {"/gsm/lc/01"},
+  {"/gsm/lc/02"},
+  {"/gsm/lc/03"},
+  {"/gsm/lc/04"},
+  {"/gsm/lc/05"}
+};
+#endif
+
+#if defined(_TMS470)
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_LCS                                            |
+| STATE   : code             ROUTINE : store_lc_flag_nvm                                        |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function stores the LC flag in NVM
+*/
+
+T_ACI_RETURN store_lc_flag_nvm(BOOL lc_flag)
+{
+   TRACE_FUNCTION ("store_lc_flag_nvm ()");
+
+   switch(FFS_mkdir("/gsm/lc"))
+   {/* create/check ffs directory for LC clients */
+      case EFFS_OK:
+      case EFFS_EXISTS:
+        break;
+      default:
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+        return ( AT_FAIL );
+   }
+   if(FFS_fwrite("/gsm/lc/lc_flag",&location_service_flag, sizeof(BOOL)) NEQ EFFS_OK)
+   {
+       ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+       return ( AT_FAIL );
+   }
+   return AT_CMPL;
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_LCS                      |
+| STATE   : code             ROUTINE : store_lc_per_flag_nvm        |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function stores the LC periodic update flag in NVM
+*/
+
+T_ACI_RETURN store_lc_per_flag_nvm(BOOL lc_per_flag)
+{
+   TRACE_FUNCTION ("store_lc_per_flag_nvm ()");
+
+   switch(FFS_mkdir("/gsm/lc"))
+   {/* create/check ffs directory for LC clients */
+        case EFFS_OK:
+        case EFFS_EXISTS:
+          break;
+        default:
+            ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+            return ( AT_FAIL );
+   }
+   if(FFS_fwrite("/gsm/lc/lc_per_flag",&eotd_periodic_update_flag, sizeof(BOOL)) NEQ EFFS_OK)
+   {
+      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+       return ( AT_FAIL );
+   }
+   return AT_CMPL;
+}
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_LCS                                            |
+| STATE   : code             ROUTINE : store_lc_clients_nvm                                     |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function stores the LC clients in FFS
+*/
+T_ACI_RETURN store_lc_clients_nvm(void)
+{
+   T_LOC_SERV_PARA *p_lsprm = 0;
+   T_LOC_SERV_CLIENT *p_client = 0;
+   char client_index;
+
+   TRACE_FUNCTION ("store_lc_clients_nvm ()");
+
+   p_lsprm = &locServPrm;       /* global structure LC parameters */
+   p_client = p_lsprm->clients;
+   if(p_client NEQ NULL)
+   {
+       client_index = 0;
+      do
+      {
+          if(FFS_fwrite(lc_client_list[client_index],p_client, sizeof(*p_client)) NEQ EFFS_OK)
+          {
+              ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+              return ( AT_FAIL );
+          }
+TRACE_EVENT_P1("store_lc_clients_nvm success index=%d", client_index);
+          client_index++;
+           p_client = p_client->next;
+       }
+      while(p_client NEQ NULL);
+    }
+    return ( AT_CMPL );
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_LCS                                            |
+| STATE   : code             ROUTINE : remove_lc_clients_nvm                                     |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function removes the last LC client from FFS
+*/
+T_ACI_RETURN remove_lc_clients_nvm(void)
+{
+  T_LOC_SERV_PARA *p_lsprm = 0;
+  T_LOC_SERV_CLIENT *p_client = 0;
+  char client_index = 0;
+
+  TRACE_FUNCTION ("remove_lc_clients_nvm ()");
+
+  p_lsprm = &locServPrm;       /* global structure LC parameters */
+  for (p_client = p_lsprm->clients; p_client NEQ NULL AND p_client->next NEQ NULL;)
+  {
+    client_index++;
+    p_client = p_client->next;
+  }
+
+  if(FFS_remove(lc_client_list[client_index]) NEQ EFFS_OK)
+  {
+    TRACE_EVENT("remove_lc_clients_nvm error");
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return ( AT_FAIL );
+  }
+  TRACE_EVENT_P1("remove_lc_clients_nvm success index=%s", lc_client_list[client_index]);
+  return ( AT_CMPL );
+}
+#endif
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_LCS                                            |
+| STATE   : code             ROUTINE : store_lc_clsa_addr_nvm                                        |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function stores the source and destination information
+            of +CLSA in NVM
+*/
+
+T_ACI_RETURN store_lc_clsa_addr_nvm(T_LOC_MLC_ADDRESS *src_addr, T_LOC_MLC_ADDRESS *dest_addr)
+{
+   TRACE_FUNCTION ("store_lc_clsa_addr_nvm ()");
+
+#if defined(_TMS470)
+   switch(FFS_mkdir("/gsm/lc"))
+   {/* create/check ffs directory for LC clients */
+      case EFFS_OK:
+      case EFFS_EXISTS:
+        break;
+      default:
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+        return ( AT_FAIL );
+   }
+   if(FFS_fwrite("/gsm/lc/lc_src_addr",src_addr, sizeof(T_LOC_MLC_ADDRESS)) NEQ EFFS_OK)
+   {
+       ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+       return ( AT_FAIL );
+   }
+   if(FFS_fwrite("/gsm/lc/lc_dest_addr",dest_addr, sizeof(T_LOC_MLC_ADDRESS)) NEQ EFFS_OK)
+   {
+       ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+       return ( AT_FAIL );
+   }
+#endif
+   return AT_CMPL;
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_LCS                                            |
+| STATE   : code             ROUTINE : sAT_PlusCLSA                                              |
++-------------------------------------------------------------------+
+
+  PURPOSE : This is the functional counterpart of the +CLSA
+            AT command which is responsible for setting the
+            Service Mobile Location Center source and
+            destination address.
+
+            <mlcsc>: mobile location center source address
+            <mlcda>: mobile location center destination address
+*/
+GLOBAL T_ACI_RETURN sAT_PlusCLSA ( T_ACI_CMD_SRC srcId,
+                                   CHAR*    mlcsc,
+                                   CHAR*    mlcda )
+{
+   T_LOC_SERV_PARA *p_lsprm = 0;
+   char * rest_addr;
+
+   TRACE_FUNCTION ("sAT_PlusCLSA ()");
+  /*
+   *-----------------------------------------------------------------
+   * check command source
+   *-----------------------------------------------------------------
+   */
+   if(!cmh_IsVldCmdSrc (srcId))
+   {
+     ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec);
+     return( AT_FAIL );
+   }
+
+   p_lsprm = &locServPrm; /* global structure LC parameters */
+   memset(p_lsprm->mlcsrc.address,0,MAX_SMS_ADDR_DIG);
+   memset(p_lsprm->mlcdest.address,0,MAX_SMS_ADDR_DIG);
+  /*
+   *-----------------------------------------------------------------
+   * check type of number of SMLC source address
+   *-----------------------------------------------------------------
+   */
+   rest_addr = mlcsc;
+   rest_addr = cmh_setToaDef (mlcsc, &p_lsprm -> mlcsrc.toa);
+  /*
+   *-----------------------------------------------------------------
+   * process the <mlcsc> parameter
+   *-----------------------------------------------------------------
+   */
+   if ( rest_addr NEQ NULL )
+   {
+     strncpy(p_lsprm->mlcsrc.address,rest_addr,strlen(rest_addr));
+  /*
+   *-----------------------------------------------------------------
+   * check type of number of SMLC destination address
+   *-----------------------------------------------------------------
+   */
+     rest_addr = mlcda;
+     rest_addr = cmh_setToaDef (mlcda, &p_lsprm -> mlcdest.toa);
+  /*
+   *-----------------------------------------------------------------
+   * process the <mlcda> parameter
+   *-----------------------------------------------------------------
+   */
+     if ( rest_addr NEQ NULL )
+     {
+       strncpy(p_lsprm->mlcdest.address,rest_addr,strlen(rest_addr));
+       store_lc_clsa_addr_nvm(&p_lsprm->mlcsrc,&p_lsprm->mlcdest);
+     }
+     else
+     {
+       ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+       return ( AT_FAIL );
+     }
+     return ( AT_CMPL );
+   }
+   else
+   {
+     ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+     return ( AT_FAIL );
+   }
+}
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_LCS                                            |
+| STATE   : code             ROUTINE : sAT_PlusCLOM                                              |
++-------------------------------------------------------------------+
+
+  PURPOSE : This is the functional counterpart of the +CLOM
+            AT command which is responsible for handling of feature
+            flag LC and LC clients
+
+            <clomset>:     settings of CLOM
+            <lc_clientId>: client identifier
+*/
+GLOBAL T_ACI_RETURN sAT_PlusCLOM ( T_ACI_CMD_SRC srcId,
+                                   CHAR     clomset,
+                                   CHAR*    lc_clientId )
+{
+   T_LOC_SERV_PARA *p_lsprm = 0;
+   T_LOC_SERV_CLIENT *p_client = 0;
+   T_LOC_SERV_CLIENT *p_client_curr = 0;
+   T_LOC_SERV_CLIENT *p_client_prev = 0;
+   T_LOC_SERV_CLIENT *p_client_new = 0;
+   T_LOC_SERV_CLIENT *p_client_next = 0;
+   char * rest_addr = 0;
+   char client_index,clom_flag;
+   T_ACI_TOA toa_clId;
+
+   TRACE_FUNCTION ("sAT_PlusCLOM ()");
+
+   /*-----------------------------------------------------------------
+   * check command source
+   *-----------------------------------------------------------------
+   */
+   if(!cmh_IsVldCmdSrc (srcId))
+   {
+     ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+     return( AT_FAIL );
+   }
+   p_lsprm = &locServPrm;       /* global structure LC parameters */
+TRACE_EVENT_P4("num_client=%d location_service_flag=%d eotd_periodic_update_flag=%d clients=%08x",
+                p_lsprm->numb_lc_clients,
+                location_service_flag,
+                eotd_periodic_update_flag,
+                p_lsprm->clients);
+TRACE_EVENT_P6("SC_sAdddr=%s ton=%d npi=%d SC_dAddr=%s",
+                p_lsprm->mlcsrc.address, p_lsprm->mlcsrc.toa.ton, p_lsprm->mlcsrc.toa.npi,
+                p_lsprm->mlcdest.address, p_lsprm->mlcdest.toa.ton, p_lsprm->mlcdest.toa.npi);
+
+   switch(clomset)
+   {
+      case CLOM_LCS_UNKNOWN:   /* missing CLOM setting */
+          clom_flag = FALSE;
+          ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+           return( AT_FAIL );
+      case CLOM_LCS_NO_ACT:    /* LCS not active for certain client id or for all clients */
+          if(*lc_clientId EQ '0')    /* setting is valid for all LCS clients */
+          {/* switch OFF E-OTD feature flag */
+              location_service_flag = LOCATION_SERVICE_OFF;
+              clom_flag = TRUE;
+              /* switch OFF E-OTD of each client id */
+              if(p_lsprm->numb_lc_clients >0)
+              {
+                 p_client = p_lsprm->clients;
+                 if(p_client EQ NULL)
+                 {
+                      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+                      return ( AT_FAIL );
+                 }
+                 do
+                {
+                    p_client->client_status = CLIENT_NO_ACTIVE;
+                    p_client = p_client->next;
+                 }
+                while(p_client NEQ NULL);
+              }
+          }
+          else
+          {
+              /* look for client entry in list and reset client id status */
+              if(p_lsprm->numb_lc_clients >0)
+              {
+                 /* check type of delivered client id */
+                 memset(&toa_clId,0,sizeof(T_ACI_TOA));
+                 rest_addr = lc_clientId;
+                 rest_addr = cmh_setToaDef (lc_clientId, &toa_clId);
+                clom_flag = FALSE;
+                 p_client = p_lsprm->clients;
+                 if(p_client EQ NULL)
+                 {
+                    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+                    return ( AT_FAIL );
+                 }
+                 for(client_index=0;client_index<p_lsprm->numb_lc_clients;client_index++)
+                 {
+                    if(!strcmp(p_client->client_id.address,rest_addr))
+                    {
+                        if(toa_merge(toa_clId) EQ toa_merge(p_client->client_id.toa))
+                        {
+                           p_client->client_status = CLIENT_NO_ACTIVE;
+                           clom_flag = TRUE;
+                        }
+                    }
+                    if(!p_client->next)
+                        break;
+                    p_client = p_client->next;
+                 }
+                 if(clom_flag EQ FALSE)
+                 {
+                  ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+                  return ( AT_FAIL );
+                 }
+              }
+              else
+             { /* there are not LCS clients in the list */
+                 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+                 return ( AT_FAIL );
+              }
+          }
+#if defined(_TMS470)
+          if(clom_flag EQ TRUE)
+          {/* store all clients and lc flag */
+               store_lc_flag_nvm(location_service_flag);
+               store_lc_clients_nvm();
+          }
+#endif
+          return(AT_CMPL);
+      case CLOM_LCS_ACT:
+           if(*lc_clientId EQ '1')
+          {
+              /* switch ON E-OTD feature flag */
+              location_service_flag = LOCATION_SERVICE_ON;
+              clom_flag = TRUE;
+              /* switch ON E-OTD of each client id */
+             if(p_lsprm->numb_lc_clients >0)
+             {
+                  p_client = p_lsprm->clients;
+                  if(p_client EQ NULL)
+                  {
+                       ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+                      return ( AT_FAIL );
+                  }
+                  do
+                 {
+                     p_client->client_status = CLIENT_ACTIVE;
+                     p_client = p_client->next;
+                  }
+                 while(p_client NEQ NULL);
+             }
+          }
+          else
+          {
+              /* look for client entry in list and activate client id status */
+              if(p_lsprm->numb_lc_clients >0)
+              {
+                   /* check type of delivered client id */
+                   memset(&toa_clId,0,sizeof(T_ACI_TOA));
+                   rest_addr = lc_clientId;
+                   rest_addr = cmh_setToaDef (lc_clientId, &toa_clId);
+                  clom_flag = FALSE;
+                  p_client = p_lsprm->clients;
+                  if(p_client EQ NULL)
+                  {
+                      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+                      return ( AT_FAIL );
+                  }
+                  for(client_index=0;client_index<p_lsprm->numb_lc_clients;client_index++)
+                 {
+                    if(!strcmp(p_client->client_id.address,rest_addr))
+                   {
+                        if(toa_merge(toa_clId) EQ toa_merge(p_client->client_id.toa))
+                       {
+                           p_client->client_status = CLIENT_ACTIVE;
+                           clom_flag = TRUE;
+                       }
+                   }
+                   if(!p_client->next)
+                      break;
+                   p_client = p_client->next;
+                 }
+                 if(clom_flag EQ FALSE)
+                {
+                   ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+                   return ( AT_FAIL );
+                 }
+              }
+              else
+              { /* there are not LCS clients in the list */
+                  ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+                  return ( AT_FAIL );
+              }
+          }
+#if defined(_TMS470)
+          if(clom_flag EQ TRUE)
+          {/* store all clients and lc flag */
+              store_lc_flag_nvm(location_service_flag);
+               store_lc_clients_nvm();
+          }
+#endif
+            return(AT_CMPL);
+      case CLOM_LCS_CLIENT_DEL:
+       /* look for client entry in list and reset client id status */
+              clom_flag = FALSE;
+              if(p_lsprm->numb_lc_clients >0)
+             {
+                 /* check type of delivered client id */
+                 memset(&toa_clId,0,sizeof(T_ACI_TOA));
+                 rest_addr = lc_clientId;
+                 rest_addr = cmh_setToaDef (lc_clientId, &toa_clId);
+
+               if(p_lsprm->clients EQ NULL)
+               {
+                   ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+                  return ( AT_FAIL );
+               }
+               p_client_curr = p_lsprm->clients;
+               p_client_prev = NULL;
+
+               while(p_client_curr NEQ NULL)
+               {
+                  if(!strcmp(p_client_curr->client_id.address,rest_addr))
+                 {
+                     if(toa_merge(toa_clId) EQ toa_merge(p_client_curr->client_id.toa))
+                     {
+                         p_lsprm->numb_lc_clients--;
+                         clom_flag = TRUE;
+                         break;
+                      }
+                 }
+                 p_client_prev = p_client_curr;
+                 p_client_curr = p_client_curr->next;
+               }
+               if(clom_flag EQ TRUE)
+               {
+#if defined(_TMS470)
+                remove_lc_clients_nvm();
+#endif
+                if (p_client_prev EQ NULL)
+                {/* first LC client should be removed */
+                    if (p_client_curr->next EQ NULL)
+                    {/* one element in list */
+                        p_client_curr = NULL;
+                     }
+                    else
+                    {/* overwrite LC client with the next LC client */
+                         p_client_next = p_client_curr->next;
+                         strncpy(p_client_curr->client_id.address,p_client_next->client_id.address,strlen(p_client_next->client_id.address));
+                         p_client_curr->client_id.toa.ton = p_client_next->client_id.toa.ton;
+                         p_client_curr->client_id.toa.npi = p_client_next->client_id.toa.npi;
+                         p_client_curr->client_status = p_client_next->client_status;
+                         p_client_curr->next = p_client_next->next;
+                         ACI_MFREE (p_client_next);
+#if defined(_TMS470)
+                         store_lc_clients_nvm();
+#endif
+                         return(AT_CMPL);
+                      }
+                 }
+                 else
+                 {
+                    if(p_client_curr->next NEQ NULL)
+                    {
+                      p_client_prev->next = p_client_curr->next;
+                    }
+                      ACI_MFREE (p_client_curr);
+#if defined(_TMS470)
+                      store_lc_clients_nvm();
+#endif
+                      return(AT_CMPL);
+                 }
+               }
+               else
+               {
+                   ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+                   return ( AT_FAIL );
+               }
+              }
+              else
+              { /* there are not LCS clients in the list */
+                  ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+                   return ( AT_FAIL );
+              }
+       case CLOM_LCS_CLIENT_NEW:
+               /* look for client entries in list */
+              if(p_lsprm->numb_lc_clients < MAX_NUMB_LC_CLIENTS)
+              {
+                 /* check type of delivered client id */
+                  memset(&toa_clId,0,sizeof(T_ACI_TOA));
+                  rest_addr = lc_clientId;
+                  rest_addr = cmh_setToaDef (lc_clientId, &toa_clId);
+                 p_lsprm->numb_lc_clients++;
+                 ACI_MALLOC(p_client_new,sizeof(T_LOC_SERV_CLIENT));
+                memset(p_client_new,0,sizeof(T_LOC_SERV_CLIENT));
+               for(client_index=0;client_index<MAX_NUMB_LC_CLIENTS-1;client_index++)
+              {
+                  if(p_lsprm->clients EQ NULL)
+                  {/* create new LC client and activate */
+                      p_lsprm->clients = p_client_new;
+                      strncpy(p_lsprm->clients->client_id.address,rest_addr,strlen(rest_addr));
+                      p_lsprm->clients->client_id.toa.ton = toa_clId.ton;
+                      p_lsprm->clients->client_id.toa.npi = toa_clId.npi;
+                      p_lsprm->clients->client_status = CLIENT_ACTIVE;
+                      p_lsprm->clients->period_upd_status = PERIODIC_UP_NO_ACTIVE;
+                      p_lsprm->clients->period_upd_value = CLPS_DEF_PER_UP_VALUE;/* default value 15 min */
+                      p_lsprm->clients->notify = FALSE;
+                      p_lsprm->clients->confirmation = FALSE;
+                      p_lsprm->clients->period_upd_timer = 0; /* no timer entry */
+                      p_lsprm->clients->lc_clientReference = -1;
+                      p_lsprm->clients->next = NULL;
+                      break;
+                  }
+                  else
+                 {
+                      p_client_curr = p_lsprm->clients;
+                      while(p_client_curr->next)
+                      {
+                          p_client_curr = p_client_curr->next;
+                      }
+                      p_client_curr->next = p_client_new;
+                      strncpy(p_client_curr->next->client_id.address,rest_addr,strlen(rest_addr));
+                      p_client_curr->next->client_id.toa.ton = toa_clId.ton;
+                      p_client_curr->next->client_id.toa.npi = toa_clId.npi;
+                      p_client_curr->next->client_status = CLIENT_ACTIVE;
+                      p_lsprm->clients->period_upd_status = PERIODIC_UP_NO_ACTIVE;
+                      p_lsprm->clients->period_upd_value = CLPS_DEF_PER_UP_VALUE;/* default value 15 min */
+                      p_lsprm->clients->notify = FALSE;
+                      p_lsprm->clients->confirmation = FALSE;
+                      p_lsprm->clients->period_upd_timer = 0; /* no timer entry */
+                      p_lsprm->clients->lc_clientReference = -1;
+                      p_client_curr->next->next = NULL;
+                      break;
+                 }
+              }
+#if defined(_TMS470)
+               /* store all clients and lc flag */
+              store_lc_clients_nvm();
+#endif
+               return(AT_CMPL);
+             }
+             else
+             { /*  LCS clients list is full */
+                  ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+                   return ( AT_FAIL );
+             }
+       default:
+          ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+          return( AT_FAIL );
+   }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)                          MODULE  : CMH_LCS                      |
+| STATE   : code                                      ROUTINE : cmhLC_posDataReq             |
++-------------------------------------------------------------------+
+
+  PURPOSE : This function sends the primitive MNLC_SMS_MEAS_REQ
+
+            <client_id>:  service id requesting position data
+            <lcCallRefId>:  SMS reference ID
+*/
+GLOBAL void cmhLC_posDataReq (char*    clientId,
+                                                              USHORT   lcCallRefId)
+{
+   char client_id_bcd[MAX_SMS_ADDR_DIG];
+   UBYTE max_bcd,max_packed_bcd;
+
+   TRACE_FUNCTION ("cmhLC_posDataReq ()");
+   {
+        PALLOC (mnlc_sms_meas_req, MNLC_SMS_MEAS_REQ);
+
+        mnlc_sms_meas_req->reference = lcCallRefId;
+        max_bcd =(UBYTE) utl_dialStr2BCD (clientId,(UBYTE *)client_id_bcd,(UBYTE)strlen(clientId));
+        max_packed_bcd =(UBYTE)cmh_packBCD(mnlc_sms_meas_req->called_party_bcd_num.bcd, (UBYTE *)client_id_bcd, (USHORT)max_bcd);
+        mnlc_sms_meas_req->called_party_bcd_num.number_length = max_packed_bcd;
+
+        PSENDX(LC,mnlc_sms_meas_req);
+   }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_LCS                                            |
+| STATE   : code             ROUTINE : sAT_PlusCLPS                                              |
++-------------------------------------------------------------------+
+
+  PURPOSE : This is the functional counterpart of the +CLPS
+            AT command which is responsible for request the
+            position data of MS
+          <clpsset>:       enabled/disabled feature Periodic Update Setting
+          <lc_clientId>:   client address requesting position data
+          <cltimer>:       periodic update value
+*/
+GLOBAL T_ACI_RETURN sAT_PlusCLPS ( T_ACI_CMD_SRC srcId,
+                                                                     CHAR     clpsset,
+                                                                     CHAR*    lcclientId,
+                                                                     USHORT   cltimer)
+{
+   T_LOC_SERV_PARA *p_lsprm = 0;
+   T_LOC_SERV_CLIENT *p_client = 0;
+   char * rest_addr = 0;
+   char client_index,clps_flag;
+   T_ACI_TOA toa_clId;
+   USHORT lc_callref;
+   TRACE_FUNCTION ("sAT_PlusCLPS ()");
+
+   /*-----------------------------------------------------------------
+   * check command source
+   *-----------------------------------------------------------------
+   */
+   if(!cmh_IsVldCmdSrc (srcId))
+   {
+     ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+     return( AT_FAIL );
+   }
+   p_lsprm = &locServPrm;       /* global structure LC parameters */
+   switch(clpsset)
+   {
+      case CLPS_LCS_UNKNOWN:   /* missing CLPS setting */
+         clps_flag = FALSE;
+         ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+         return( AT_FAIL );
+       case CLPS_LCS_NO_ACT:    /* Periodic Update not active for certain client id or for all clients */
+            if(*lcclientId EQ '0')    /* setting is valid for all LCS clients */
+            {/* switch OFF periodic update feature flag */
+                 eotd_periodic_update_flag = PERIODIC_UPDATE_OFF;
+                 clps_flag = TRUE;
+                  /* switch OFF periodic update of each client id */
+                  if(p_lsprm->numb_lc_clients >0)
+                  {
+                     p_client = p_lsprm->clients;
+                     if(p_client EQ NULL)
+                     {
+                        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CLPSClientNotRec);
+                         return ( AT_FAIL );
+                     }
+                     do
+                     {
+                         p_client->period_upd_status = PERIODIC_UP_NO_ACTIVE;
+                         p_client->period_upd_value = CLPS_DEF_PER_UP_VALUE;
+                         p_client = p_client->next;
+                     }
+                     while(p_client NEQ NULL);
+                  }
+            }
+            else
+            {
+                 /* look for client entry in list and reset client id status */
+                 if(p_lsprm->numb_lc_clients >0)
+                 {
+                     /* check type of delivered client id */
+                     memset(&toa_clId,0,sizeof(T_ACI_TOA));
+                     rest_addr = lcclientId;
+                     rest_addr = cmh_setToaDef (lcclientId, &toa_clId);
+                    clps_flag = FALSE;
+                    p_client = p_lsprm->clients;
+                    if(p_client EQ NULL)
+                   {
+                        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CLPSClientNotRec );
+                        return ( AT_FAIL );
+                   }
+                   for(client_index=0;client_index<p_lsprm->numb_lc_clients;client_index++)
+                   {
+                      if(!strcmp(p_client->client_id.address,rest_addr))
+                      {
+                          if(toa_merge(toa_clId) EQ toa_merge(p_client->client_id.toa))
+                          {
+                              p_client->period_upd_status = PERIODIC_UP_NO_ACTIVE;
+                              p_client->period_upd_value = CLPS_DEF_PER_UP_VALUE;
+                               clps_flag = TRUE;
+                          }
+                      }
+                      if(!p_client->next)
+                        break;
+                      p_client = p_client->next;
+                   }
+                    if(clps_flag EQ FALSE)
+                    {
+                        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CLPSClientNotRec );
+                        return ( AT_FAIL );
+                    }
+                 }
+                 else
+                { /* there are not LCS clients in the list */
+                    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CLPSClientNotRec );
+                    return ( AT_FAIL );
+                }
+            }
+#if defined(_TMS470)
+            if(clps_flag EQ TRUE)
+            {/* store all clients and lc flag */
+                store_lc_per_flag_nvm(eotd_periodic_update_flag);
+                store_lc_clients_nvm();
+            }
+#endif
+            clps_flag = FALSE;
+            return(AT_CMPL);
+      case CLPS_LCS_ACT:
+            if(cltimer NEQ IMM_POS_DATA_REQ)
+            {
+                if(*lcclientId EQ '1')
+               {
+                  /* switch ON E-OTD feature flag */
+                  eotd_periodic_update_flag = PERIODIC_UPDATE_ON;
+                  clps_flag = TRUE;
+                  /* switch ON periodic update of each client id */
+                  if(p_lsprm->numb_lc_clients >0)
+                  {
+                      p_client = p_lsprm->clients;
+                      if(p_client EQ NULL)
+                      {
+                          ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CLPSClientNotRec );
+                           return ( AT_FAIL );
+                      }
+                      do
+                      {
+                          p_client->period_upd_status = PERIODIC_UP_ACTIVE;
+                          /* start position data request */
+                          lc_callref = (USHORT)lc_callref_init();
+                          if(!lc_callref)
+                          {
+                              ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec);
+                              return ( AT_FAIL );
+                          }
+                          p_client->lc_clientReference = lc_callref;
+                          cmhLC_posDataReq (p_client->client_id.address, lc_callref);
+                          p_client = p_client->next;
+                       }
+                       while(p_client NEQ NULL);
+                  }
+               }
+              else
+              {
+                 /* look for client entry in list and activate client id status */
+                 if(p_lsprm->numb_lc_clients >0)
+                 {
+                      /* check type of delivered client id */
+                    memset(&toa_clId,0,sizeof(T_ACI_TOA));
+                    rest_addr = lcclientId;
+                    rest_addr = cmh_setToaDef (lcclientId, &toa_clId);
+                    clps_flag = FALSE;
+                    p_client = p_lsprm->clients;
+                    if(p_client EQ NULL)
+                    {
+                        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CLPSClientNotRec );
+                        return ( AT_FAIL );
+                    }
+                    for(client_index=0;client_index<p_lsprm->numb_lc_clients;client_index++)
+                   {
+                      if(!strcmp(p_client->client_id.address,rest_addr))
+                      {
+                          if(toa_merge(toa_clId) EQ toa_merge(p_client->client_id.toa))
+                          {
+                              p_client->period_upd_status = PERIODIC_UP_ACTIVE;
+                              if(cltimer<=120)
+                                p_client->period_upd_value = cltimer;
+                              else
+                              {
+                                 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_IntervalNotSup);
+                                 return ( AT_FAIL );
+                              }
+                              clps_flag = TRUE;
+                               /* start position data request */
+                              lc_callref = (USHORT)lc_callref_init();
+                              if(!lc_callref)
+                              {
+                                  ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+                                  return ( AT_FAIL );
+                              }
+                              p_client->lc_clientReference = lc_callref;
+                              cmhLC_posDataReq (p_client->client_id.address,lc_callref);
+                          }
+                      }
+                      if(!p_client->next)
+                        break;
+                      p_client = p_client->next;
+                   }
+                   if(clps_flag EQ FALSE)
+                  {
+                      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CLPSClientNotRec );
+                      return ( AT_FAIL );
+                   }
+                 }
+                 else
+                 { /* there are not LCS clients in the list */
+                      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CLPSClientNotRec );
+                      return ( AT_FAIL );
+                 }
+              }
+              if(clps_flag EQ TRUE)
+              { /* store all clients and lc flag */
+#if defined(_TMS470)
+                 store_lc_per_flag_nvm(eotd_periodic_update_flag);
+                 store_lc_clients_nvm();
+#endif
+                 clps_flag = FALSE;
+                 return ( AT_EXCT );
+               }
+               return(AT_CMPL);   /* no position data request */
+            }
+            else /* immediately position data request (via CLSA, SMS) */
+            {
+                 lc_callref = (USHORT)lc_callref_init();
+                 if(!lc_callref)
+                {
+                    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+                    return ( AT_FAIL );
+                 }
+                 p_lsprm->lc_callReference = lc_callref;
+                 cmhLC_posDataReq (lcclientId,lc_callref);
+                 return ( AT_EXCT );
+            }
+      default:
+          ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+          return ( AT_FAIL );
+   }
+}
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)                          MODULE  : CMH_LCS                      |
+| STATE   : code                                          ROUTINE : sAT_PlusCLSR                 |
++-------------------------------------------------------------------+
+
+  PURPOSE : This is the functional counterpart of the +CLSR
+            AT command which is responsible for setting of privacy parameters,
+            request position data (not supported currently RM 10-25-02)
+            setup call (not supported currently RM 10-25-02)
+          <lcnotify>:       enabled/disabled feature user notification
+          <lcconfirm>:    enabled/disabled feature user confirmation
+          <lc_clientId>:   client address requesting position data
+*/
+GLOBAL T_ACI_RETURN sAT_PlusCLSR ( T_ACI_CMD_SRC srcId,
+                                                                    CHAR      lcnotify,
+                                                                    CHAR      lcconfirm,
+                                                                    CHAR*    lcclientId)
+
+{
+   T_LOC_SERV_PARA *p_lsprm = 0;
+   T_LOC_SERV_CLIENT *p_client = 0;
+   char * rest_addr = 0;
+   char client_index,clsr_flag;
+   T_ACI_TOA toa_clId;
+
+   TRACE_FUNCTION ("sAT_PlusCLSR ()");
+
+   /*-----------------------------------------------------------------
+   * check command source
+   *-----------------------------------------------------------------
+   */
+   if(!cmh_IsVldCmdSrc (srcId))
+   {
+     ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+     return( AT_FAIL );
+   }
+   p_lsprm = &locServPrm;       /* global structure LC parameters */
+   switch(lcnotify)
+   {
+       case CLRS_NO_USER_NOTIFY: /* state notify */
+                /* look for client entry in list and reset client id status */
+                    if(p_lsprm->numb_lc_clients >0)
+                    {
+                        /* check type of delivered client id */
+                        memset(&toa_clId,0,sizeof(T_ACI_TOA));
+                        rest_addr = lcclientId;
+                        rest_addr = cmh_setToaDef (lcclientId, &toa_clId);
+                         clsr_flag = FALSE;
+                          p_client = p_lsprm->clients;
+                          if(p_client EQ NULL)
+                          {
+                              ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CLSRClientIdNotRec);
+                              return ( AT_FAIL );
+                          }
+                          for(client_index=0;client_index<p_lsprm->numb_lc_clients;client_index++)
+                          {
+                              if(!strcmp(p_client->client_id.address,rest_addr))
+                              {
+                                  if(toa_merge(toa_clId) EQ toa_merge(p_client->client_id.toa))
+                                  {
+                                     if(lcconfirm EQ CLRS_NO_USER_CONFIRM)
+                                      {
+                                          p_client->confirmation = p_client->notify = FALSE;
+                                          clsr_flag = TRUE;
+                                      }
+                                     else if(lcconfirm EQ CLRS_USER_CONFIRM)
+                                      {
+                                              p_client->notify = FALSE;
+                                              p_client->confirmation = TRUE;
+                                              clsr_flag = TRUE;
+                                      }
+                                     else
+                                      {
+                                            ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_UsConfReqTyNotRec );
+                                            return( AT_FAIL );
+                                      }
+                                  }
+                              }
+                              if(!p_client->next)
+                                 break;
+                              p_client = p_client->next;
+                          }
+                          if(clsr_flag EQ FALSE)
+                          {
+                              ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CLSRClientIdNotRec );
+                              return ( AT_FAIL );
+                          }
+                    }
+                    else
+                    { /* there are not LCS clients in the list */
+                        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CLSRClientIdNotRec );
+                        return ( AT_FAIL );
+                    }
+                    break;
+       case CLRS_USER_NOTIFY:
+                /* look for client entry in list and reset client id status */
+                    if(p_lsprm->numb_lc_clients >0)
+                    {
+                        /* check type of delivered client id */
+                        memset(&toa_clId,0,sizeof(T_ACI_TOA));
+                        rest_addr = lcclientId;
+                        rest_addr = cmh_setToaDef (lcclientId, &toa_clId);
+                         clsr_flag = FALSE;
+                          p_client = p_lsprm->clients;
+                          if(p_client EQ NULL)
+                          {
+                              ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CLSRClientIdNotRec );
+                              return ( AT_FAIL );
+                          }
+                          for(client_index=0;client_index<p_lsprm->numb_lc_clients;client_index++)
+                          {
+                              if(!strcmp(p_client->client_id.address,rest_addr))
+                              {
+                                  if(toa_merge(toa_clId) EQ toa_merge(p_client->client_id.toa))
+                                  {
+                                     if(lcconfirm EQ CLRS_NO_USER_CONFIRM)
+                                      {
+                                          p_client->confirmation =  FALSE;
+                                          p_client->notify = TRUE;
+                                          clsr_flag = TRUE;
+                                      }
+                                     else if(lcconfirm EQ CLRS_USER_CONFIRM)
+                                      {
+                                              p_client->confirmation = p_client->notify = TRUE;
+                                              clsr_flag = TRUE;
+                                      }
+                                     else
+                                      {
+                                            ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_UsConfReqTyNotRec );
+                                            return( AT_FAIL );
+                                      }
+                                  }
+                              }
+                              if(!p_client->next)
+                                 break;
+                              p_client = p_client->next;
+                          }
+                          if(clsr_flag EQ FALSE)
+                          {
+                              ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CLSRClientIdNotRec );
+                              return ( AT_FAIL );
+                          }
+                    }
+                    else
+                    { /* there are not LCS clients in the list */
+                        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CLSRClientIdNotRec );
+                        return ( AT_FAIL );
+                    }
+                    break;
+       case CLRS_NOTIFY_UNKNOWN:   /* missing CLSR notify setting */
+       default:
+         clsr_flag = FALSE;
+         ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_LCS_CmdNotRec );
+         return( AT_FAIL );
+   }
+#if defined(_TMS470)
+   if(clsr_flag EQ TRUE)
+   {/* store all clients  */
+            store_lc_clients_nvm();
+            clsr_flag = FALSE;
+    }
+#endif
+    return(AT_CMPL);
+}
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_LCS                                       |
+|                                 ROUTINE : cmhSMS_MEASdeliver                                     |
++-------------------------------------------------------------------+
+
+  PURPOSE : process delivered position data of LC
+*/
+GLOBAL void cmhSMS_MEASdeliver ( UBYTE *lc_meas_buf)
+{
+   T_ATI_SRC_PARAMS *src_params = find_element( ati_src_list, locServPrm.lc_src_id, search_ati_src_id);
+
+   TRACE_FUNCTION ("cmhSMS_MEASdeliver ()");
+
+   memset(&aci_lc_data.position_data,0,MAX_POSITION_DATA);
+   aci_lc_data.pos_data_length = MAX_POSITION_DATA;
+   memcpy(&aci_lc_data.position_data,lc_meas_buf,MAX_POSITION_DATA);
+   rCI_PlusCLPS(locServPrm.lc_src_id, &aci_lc_data);
+   if(src_params->curAtCmd EQ AT_CMD_CLPS)
+   {
+       srcId_cb = locServPrm.lc_src_id;
+       rCI_OK(AT_CMD_CLPS);
+   }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_LCS                                       |
+|                                 ROUTINE : lclist_init                                                         |
++-------------------------------------------------------------------+
+
+  PURPOSE : initialize LC parameter list
+*/
+T_ACI_RETURN lclist_init (void)
+{
+  T_LOC_SERV_PARA *lc_para = 0;
+  T_LOC_SERV_CLIENT *p_client = 0;
+#if defined(_TMS470)
+  T_LOC_SERV_CLIENT **p_client_chain;
+  char client_index;
+  T_LC_NVM_DATA lc_nvm_data;
+#endif
+
+  TRACE_FUNCTION ("lclist_init ()");
+  lc_para = &locServPrm;
+
+#if defined(_TMS470)
+
+  memset(&lc_nvm_data,0,sizeof(T_LC_NVM_DATA));
+
+  switch(FFS_mkdir("/gsm/lc"))
+  {/* check ffs directory for LC clients and test conditions */
+    case EFFS_EXISTS:
+      if(FFS_fread("/gsm/lc/lc_flag",&location_service_flag, sizeof(BOOL)) NEQ sizeof(BOOL))
+      {
+        location_service_flag = FALSE;
+      }
+      if(FFS_fread("/gsm/lc/lc_per_flag",&eotd_periodic_update_flag, sizeof(BOOL)) NEQ sizeof(BOOL))
+      {
+        eotd_periodic_update_flag = FALSE;
+      }
+
+      lc_para->lc_callReference = -1;
+      if(FFS_fread("/gsm/lc/lc_src_addr",&lc_para->mlcsrc, sizeof(T_LOC_MLC_ADDRESS)) NEQ sizeof(T_LOC_MLC_ADDRESS))
+        memset(&lc_para->mlcsrc,0,sizeof(T_LOC_MLC_ADDRESS));
+
+      if(FFS_fread("/gsm/lc/lc_dest_addr",&lc_para->mlcdest, sizeof(T_LOC_MLC_ADDRESS)) NEQ sizeof(T_LOC_MLC_ADDRESS))
+        memset(&lc_para->mlcdest,0,sizeof(T_LOC_MLC_ADDRESS));
+
+      lc_para->numb_lc_clients = 0;
+      lc_para->clients = NULL;
+      p_client_chain = &lc_para->clients;
+      for(client_index = 0; client_index<MAX_NUMB_LC_CLIENTS;client_index++)
+      {
+        ACI_MALLOC(p_client,sizeof(T_LOC_SERV_CLIENT));
+        memset(p_client,0,sizeof(T_LOC_SERV_CLIENT));
+        if(FFS_fread(lc_client_list[client_index],p_client, sizeof(T_LOC_SERV_CLIENT)) EQ sizeof(T_LOC_SERV_CLIENT))
+        {
+          lc_para->numb_lc_clients++;
+          *p_client_chain = p_client;
+          p_client_chain = &(p_client->next);
+        }
+        else
+        {
+          ACI_MFREE(p_client);
+          break;
+        }
+      }
+
+      if(FFS_fread("/gsm/lc/lc_test",&lc_nvm_data, sizeof(lc_nvm_data)) NEQ sizeof(lc_nvm_data))
+      {
+        memset(&lc_nvm_data, 0, sizeof(lc_nvm_data));
+        lc_nvm_data.sleep = TRUE; /* don't switch off any sleep mode */
+      }
+
+      if (lc_nvm_data.cps_trace)
+      {
+       lc_cps_traces = TRUE;
+       lc_msmsnr = 0;
+      }
+
+      if (lc_nvm_data.eotd)
+       v_eotd = TRUE;
+
+      if (lc_nvm_data.periodic AND eotd_periodic_update_flag EQ PERIODIC_UPDATE_ON )
+      {
+       ULONG timer = 0;
+
+       for(p_client = lc_para->clients; p_client NEQ NULL; p_client = p_client->next)
+       {
+         timer = p_client->period_upd_value*60*1000;/* sec */
+         if (p_client->period_upd_timer EQ 0)
+           p_client->period_upd_timer = search_tim_handl();
+
+         if(p_client->period_upd_timer NEQ 0  AND
+            p_client->period_upd_status EQ PERIODIC_UP_ACTIVE)
+         {
+           TIMERSTART( timer, p_client->period_upd_timer);
+         }
+       }
+      }
+
+      if (!lc_nvm_data.sleep)
+      {
+       /* definitions adopted from cst.h */
+       #define NO_SLEEP            0
+       #define ARMIO_CLK           0x0001
+       #define UWIRE_CLK           0x0020
+       #define SIM_CLK             0x0040
+       #define UART_CLK            0x0400
+
+       power_down_config(NO_SLEEP, ARMIO_CLK | UWIRE_CLK | SIM_CLK | UART_CLK);
+      }
+      break;
+    default:
+      /* initialize list, no lc clients and no lc test conditions in ffs */
+      memset(&lc_para->mlcsrc,0,sizeof(T_LOC_MLC_ADDRESS));
+      memset(&lc_para->mlcdest,0,sizeof(T_LOC_MLC_ADDRESS));
+      lc_para->lc_callReference = -1;
+      location_service_flag = LOCATION_SERVICE_OFF;
+      eotd_periodic_update_flag = PERIODIC_UPDATE_OFF;
+      lc_para->numb_lc_clients = 0;
+      lc_para->clients = NULL;
+      break;
+  }
+#else /* win32 */
+/* initialize list */
+  memset(&lc_para->mlcsrc,0,sizeof(T_LOC_MLC_ADDRESS));
+  memset(&lc_para->mlcdest,0,sizeof(T_LOC_MLC_ADDRESS));
+  lc_para->lc_callReference = -1;
+  location_service_flag = LOCATION_SERVICE_OFF;
+  eotd_periodic_update_flag = PERIODIC_UPDATE_OFF;
+  lc_para->numb_lc_clients = 0;
+  lc_para->clients = NULL;
+#endif
+
+  return(AT_CMPL);
+}
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_LCS                                       |
+|                                 ROUTINE : lclist_deinit                                                     |
++-------------------------------------------------------------------+
+
+  PURPOSE : initialize LC parameter list
+
+GLOBAL void lclist_deinit (void)
+{
+  T_LOC_SERV_PARA *lc_para = 0;
+
+  TRACE_FUNCTION ("lclist_deinit ()");
+
+  lc_para = &locServPrm;
+  location_service_flag = LOCATION_SERVICE_OFF;
+  eotd_periodic_update_flag = PERIODIC_UPDATE_OFF;
+}*/
+
+#endif /* FF_EOTD */
+/*==== EOF ========================================================*/
+