FreeCalypso > hg > fc-magnetite
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 ========================================================*/ +