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