FreeCalypso > hg > fc-magnetite
view src/aci2/aci/cmh_lcs.c @ 646:8c74c177e914
LICENSE: new terms
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 14 Apr 2020 20:09:37 +0000 |
parents | 93999a60b835 |
children |
line wrap: on
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 ========================================================*/