diff g23m/condat/ms/src/bmi/MmiHomezone.c @ 0:509db1a7b7b8

initial import: leo2moko-r1
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 01 Jun 2015 03:24:05 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/g23m/condat/ms/src/bmi/MmiHomezone.c	Mon Jun 01 03:24:05 2015 +0000
@@ -0,0 +1,1259 @@
+/*******************************************************************************
+
+					CONDAT (UK)
+
+********************************************************************************                                                                              
+
+ This software product is the property of Condat (UK) Ltd and may not be
+ disclosed to any third party without the express permission of the owner.                                 
+                                                                              
+********************************************************************************
+
+ $Project name:	Basic MMI                                                      
+ $Project code:	BMI                                                            
+ $Module:		
+ $File:		    MmiHomezone.c
+ $Revision:		1.0                                                       
+                                                                              
+ $Author:		Condat(UK)                                                         
+ $Date:		    15/02/02                                                      
+                                                                               
+********************************************************************************
+                                                                              
+ Description: Homezone functionality in MMI
+ 
+   
+                        
+********************************************************************************
+
+ $History: MmiHomezone.c
+
+	15/02/02			Original Condat(UK) BMI version.
+	28/05/02			Latest Condat(UK) BMI version
+
+	Mar 14, 2006 DR: OMAPS00061468 - x0035544.
+   	Description: SAT 27.22.4.22.2 SET UP IDLE MODE TEXT (Icon support) fails 
+   	Solution : In the function homezoneUpdateDisplay(), additional parameter has been added to the
+   	function call addSatMessage() under the flag FF_MMI_SAT_ICON to support SAT Icon for IDLE TEXT display.
+
+       Dec 15, 2005   REF: MMI-FIX-OMAPS00058684 x0035544
+       Description: OMAPS00045726 / MMI-FIX-30439 Follow-Up : ifdef for FF Home Zone forgotten.
+       Solution: Added Feature flag FF_HOMEZONE for the function sms_homezoneCBToggle(U8 Activate_CB)
+       in this file as it has got the prototype for this function.
+       
+	Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+   	Description: The homezone/cityzone tags were not being displayed properly.
+   	Solution: Modified to save the tags properly in caches and also made the 
+	appropriate modifications to update the same properly during mobility.
+	   
+ $End
+
+*******************************************************************************/
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined (NEW_FRAME)
+
+#include "typedefs.h"
+#include "vsi.h"
+#include "pei.h"
+#include "custom.h"
+#include "gsm.h"
+
+#else
+
+#include "STDDEFS.H"
+#include "custom.h"
+#include "gsm.h"
+#include "vsi.h"
+
+#endif
+
+
+#include "mfw_sys.h"
+
+#include "mfw_mfw.h"
+#include "mfw_win.h"
+#include "mfw_kbd.h"
+/* SPR#1428 - SH - New Editor changes */
+#ifndef NEW_EDITOR
+#include "mfw_edt.h"
+#endif
+#include "mfw_lng.h"
+#include "mfw_icn.h"
+#include "mfw_phb.h"
+#include "mfw_sim.h"
+#include "mfw_nm.h"
+#include "ksd.h"
+#include "psa.h"
+#include "mfw_sms.h"
+#include "mfw_smsi.h"
+#include "mfw_mnu.h"
+#include "mfw_sat.h"
+#include "mfw_tim.h"
+#include "mfw_cphs.h"
+
+#include "MmiMmi.h"
+#include "MmiDummy.h"
+#include "MmiDialogs.h"
+#include "MmiLists.h"
+
+#include "MmiMain.h"
+#include "MmiStart.h"
+#include "MmiPins.h"
+#include "MmiMenu.h"
+#include "MmiSoftKeys.h"
+#include "MmiSounds.h"
+#include "mmiCall.h"
+
+#include "MmiBookController.h"
+
+#include "MmiIdle.h"
+#include "Mmiicons.h"
+#include "MmiNetwork.h"
+#include "mmiSmsBroadcast.h"
+#include "MmiHomezone.h"
+
+#include "cus_aci.h"
+
+#include "prim.h"
+#ifndef PCM_2_FFS
+#include "pcm.h"
+#endif
+
+
+//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+// enable HZ trace 
+//#undef	TRACE_MMIHOMEZONE
+#define TRACE_MMIHOMEZONE 1
+
+T_homezone_data		homezoneData;
+extern T_SMSCB_DATASTORE g_smscb_data; /* storage for Cell Broadcast lists */
+static int  hzFlag = 0; //Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+
+//Dec 14, 2005 REF: MMI-FIX-OMAPS00058684 x0035544
+#ifdef FF_HOMEZONE
+//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+// Externed the function for activation\deactivation of Homezone.
+extern void sms_homezoneCBToggle(U8 Activate_CB);
+#endif
+//void sms_homezoneCBToggle(U8 Activate_CB);
+
+/*******************************************************************************
+
+LOCALLY REFERENCED FUNCTIONS
+
+*******************************************************************************/
+
+void		homezoneReadParams();
+void		homezoneLocate();
+static U32	calculateDecimal( char *string, int length );
+static U32	readHexFromSimfile( UBYTE *simFile, int length );
+static void	writeHexToSimfile( UBYTE *simFile, U32 value, int length );
+
+/*******************************************************************************
+
+ $Function:    	homezoneInit
+
+ $Description:	Initialise homezone data structure.  Reset the recent cache.
+ 
+ $Returns:		
+
+ $Arguments:
+*******************************************************************************/
+
+void homezoneInit()
+{
+	T_homezone_data	*data			= &homezoneData;
+	USHORT cacheIndex;
+	//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+	// Added the following local variables.
+	//begin 30439
+	UBYTE          version; 
+	USHORT         max_rcd;
+	EF_HZCACHE     cache;
+	//end 30439
+	
+	TRACE_FUNCTION("homezoneInit()");
+
+	/* Set all data to 0 */
+
+	memset((UBYTE *)data, 0, sizeof(T_homezone_data));
+
+	data->current_zone = HZ_NOT_IN_ZONE;									// 0xFF = not in a homezone
+	data->recent_cell_index = HZ_RECENT_MAX-1;								// Next entry will loop round & be at start of cache
+
+	/* Set up recent cell cache */
+	
+	for (cacheIndex = 0; cacheIndex<HZ_RECENT_MAX; cacheIndex++)
+	{
+		data->recent_cell[cacheIndex] = 0;
+		data->recent_cell_zone[cacheIndex] = HZ_NOT_IN_ZONE;
+		//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+		//begin 30439
+			/* Read cache from PCM */
+		if (pcm_ReadRecord((UBYTE *)EF_HZCACHE_ID,
+                         (USHORT)(cacheIndex+1),
+                         SIZE_EF_HZCACHE,
+                         (UBYTE *)&cache,
+                         &version,
+                         &max_rcd) NEQ DRV_OK)
+		{
+			TRACE_EVENT ("Init cache read from PCM wrong");
+			break;                                      /* read error */
+		}
+		else
+		{
+			if (cache.cid[0] != 0xFF AND cache.cid[1] != 0xFF)
+			{
+				data->recent_cell[cacheIndex] = readHexFromSimfile(&cache.cid[0],2);
+				data->recent_cell_zone[cacheIndex] = cache.zone;
+			}
+        }
+		TRACE_EVENT_P3("Init cache %d: CID %X, zone %X",cacheIndex, data->recent_cell[cacheIndex], data->recent_cell_zone[cacheIndex]);
+		//end 30439
+	}
+
+	data->new_cell_res = FALSE;
+	
+	return;
+}
+
+			
+/*******************************************************************************
+
+ $Function:    	homezoneReadSim
+
+ $Description:	Read homezone data in from SIM.  Checks to see if conditions (SIM,
+ 				network) are correct for homezone; switches it off if not.
+ 
+ $Returns:		None.
+
+ $Arguments:	read_again	- if this is HZ_READ_ONCE_ONLY, then SIM fields will not
+ 					be read in again if they have already been read in once.
+ 					If this is HZ_READ_SIM_AGAIN, they will be read in anyway.
+ 					
+*******************************************************************************/
+
+void homezoneReadSim(UBYTE read_again)
+{
+	T_homezone_data		*data = &homezoneData;
+	char IMSI[17];
+	char MNC_MCC[6];
+	T_ACI_RETURN result;
+	USHORT				networkIndex;
+	UBYTE				networkOK;
+	USHORT				tries;
+
+	/* Check if homezone is switched off */
+	
+	if (data->received == HZ_RECEIVED_HZ_OFF)
+		return;
+
+	/* SPR877 - If read_again specifies that SIM data should not be re-read, exit from function
+	 * provided we have read it once. */
+	 
+	if (read_again == HZ_READ_ONCE_ONLY && data->received & HZ_RECEIVED_SIMDATA)
+		return;
+	
+	TRACE_FUNCTION("homezoneReadSim()");
+
+	/* Check if network operator is in list */
+
+	networkOK = FALSE;
+
+	tries = 0;
+	
+	while ((result = qAT_PlusCIMI(CMD_SRC_LCL, IMSI)) != AT_CMPL  && tries < 5)
+	{
+		tries++;
+	}
+		
+	strncpy(MNC_MCC, IMSI, 5);
+	MNC_MCC[5] =0;	//terminate string
+
+#ifdef TRACE_MMIHOMEZONE
+	TRACE_EVENT_P1("MNC_MCC: %s", (char *)MNC_MCC);
+#endif
+
+	for (networkIndex=0; networkIndex<HZ_PERMITTED_NETWORKS; networkIndex++)
+	{
+		if (!strncmp((char *)MNC_MCC, homezoneMNC_MCC[networkIndex],5))
+		{
+#ifdef TRACE_MMIHOMEZONE
+			TRACE_EVENT_P1("Matches entry %d", networkIndex);
+#endif
+			networkOK = TRUE;
+		}
+	}
+	//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+	//begin 30439
+	/* Attempt to read first sim field */
+	if (read_again == HZ_READ_SIM_AGAIN)
+		hzFlag = 1;
+	//end 30439
+
+	if (networkOK)
+	{
+		if (!Read_Sim(HZ_SIM_PARAMETERS, 0, HZ_SIM_PARAMETERS_SIZE, data->buffer))
+		{
+			TRACE_EVENT("SIM read error 1: Homezone OFF");	/* SIM field not present, switch off homezone */
+			data->received = HZ_RECEIVED_HZ_OFF;
+			hzFlag = 0; //Jun 14, 2005 REF: MMI-FIX-30439 x0018858 - Seting the variable
+		}
+	}
+	else
+	{
+		TRACE_EVENT("Wrong network: Homezone OFF");		/* Network not in list, switch off homezone */
+		data->received = HZ_RECEIVED_HZ_OFF;
+		hzFlag = 0; //Jun 14, 2005 REF: MMI-FIX-30439 x0018858 - Seting the variable
+	}
+	
+	return;
+}
+
+
+/*******************************************************************************
+
+ $Function:    	homezoneReadSimCb
+
+ $Description:	Callback, called when read sim has occurred.  Fills up the homezone
+ 				data structure with the appropriate values retrieved from SIM.
+ 
+ $Returns:		None.
+
+ $Arguments: 	field - the SIM field that was just read
+ 				record - the record in the SIM field that was read
+ 				result - the result code returned - 0 for successful.
+*******************************************************************************/
+
+void homezoneReadSimCb(USHORT field, USHORT record, USHORT result)
+{
+	T_homezone_data	*data				= &homezoneData;
+	T_homezone		*homezone			= data->homezone;
+	UBYTE			*simFile;
+	USHORT			fileIndex;
+	USHORT			hzIndex;
+	UBYTE			keepLooking;
+	U8	Activate_cb =0; //Jun 14, 2005 REF: MMI-FIX-30439 x0018858 
+						//To activate/deactivate homezoneCB
+	TRACE_FUNCTION("homezoneReadSimCb()");
+	
+#ifdef TRACE_MMIHOMEZONE
+	TRACE_EVENT_P2("Have just read SIM file: %x record %d", field, record);
+#endif
+
+	/* Read in general homezone data.  If reading first SIM field fails, switch homezone off */
+
+	if (field==HZ_SIM_PARAMETERS)
+	{	
+		/* check SIM read result for homezone parameter */
+		//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+		//begin 30439
+		//Modified the conditional statement
+		//if (result)
+		if (result != 0x80FF)
+//end 30439
+		{
+			TRACE_EVENT("SIM read error 2: Homezone OFF");
+			data->received = HZ_RECEIVED_HZ_OFF;
+			hzFlag = 0; //Jun 14, 2005 REF: MMI-FIX-30439 x0018858 -Setting the variable
+			return;
+		}
+		homezoneReadParams();
+		/*homezoneActivateCB();*/				/* Switch on cell broadcast */
+		/* SH - this is already done at startup */
+		record = HZ_CACHE_MAX;
+	}
+	
+	/* Read in records for each homezone cache */
+
+	/* check SIM read result for hoemzone cache */
+	//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+	//begin 30439
+	//Modified the conditional statement
+	//if (field>HZ_SIM_PARAMETERS && !result)
+	if (field>HZ_SIM_PARAMETERS && (result == 0x80FF))
+	//end 30439
+	{
+		hzIndex = field - HZ_SIM_CELL_CACHE;
+		simFile = data->buffer2;
+		fileIndex = 0;
+		
+		homezone[hzIndex].lac[record-1] = readHexFromSimfile(&simFile[fileIndex],2);
+		fileIndex+=2;
+		homezone[hzIndex].cid[record-1] = readHexFromSimfile(&simFile[fileIndex],2);
+
+#ifdef TRACE_MMIHOMEZONE
+		TRACE_EVENT_P2("read lac = %x, cid = %x", homezone[hzIndex].lac[record-1], homezone[hzIndex].cid[record-1]);
+#endif
+	}
+
+	/* Read in the next record */
+
+	keepLooking = TRUE;
+	
+	while (keepLooking)
+	{
+		/* check SIM read result for hoemzone cache */
+		//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+		//begin 30439
+		//Modified the conditional statement
+		//if (record==HZ_CACHE_MAX || result)
+		if (record==HZ_CACHE_MAX || (result != 0x80FF))
+//end 30439
+		{
+			field++;												// Look at next field
+			record = 1;
+			//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+			// Print the current feild.
+			TRACE_EVENT_P1("current field = %x", field);
+		}
+		else
+			record++;
+
+		hzIndex = field-HZ_SIM_CELL_CACHE;
+
+		if (hzIndex==HZ_ZONES_MAX)
+		{
+			keepLooking = FALSE;
+			/* Have read all sim data, set flag so icon etc will be updated */
+			data->received |= HZ_RECEIVED_SIMDATA;
+			//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+			//begin 30439
+			/* homezone display update after SIM REFRESH (when hzFlag set to 1) */
+			TRACE_EVENT_P1("hzFlag = %d", hzFlag);
+			if (hzFlag)
+			{
+//				hzFlag = 0;
+				homezoneUpdate(0, 0, 1);
+			}
+			else
+			{
+
+				TRACE_EVENT("activate homezone CB");
+				//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+				//Call to activate the Homezone CB.
+				Activate_cb = 1;
+				sms_homezoneCBToggle(Activate_cb);
+				homezoneUpdate(0, 0, 1); /* new VO : speed up update */
+			}
+			//end 30439
+			 
+		}
+		else if (homezone[hzIndex].active)
+		{
+			keepLooking = FALSE;
+			
+#ifdef TRACE_MMIHOMEZONE
+	//TRACE_EVENT_P3("HZ READ HZ %d field %X record %d", hzIndex, field, record);
+#endif
+			if (!Read_Sim_Record(field, record, HZ_SIM_CELL_CACHE_SIZE, data->buffer2))
+			{
+				TRACE_EVENT("SIM reading error!");
+			}
+		}
+	}
+	
+	return;
+}
+
+
+/*******************************************************************************
+
+ $Function:    	homezoneReadParams
+
+ $Description:	Decode the homezone parameters from the first SIM field
+ 
+ $Returns:		None.
+
+ $Arguments:	None.
+*******************************************************************************/
+
+void homezoneReadParams()
+{
+	T_homezone_data	*data				= &homezoneData;
+	T_homezone		*homezone			= data->homezone;
+	UBYTE			*simFile;
+	USHORT			fileIndex;
+	USHORT			tagIndex;
+	USHORT			hzIndex;
+	char			character;
+
+	TRACE_FUNCTION("homezoneReadParams()");
+	
+	simFile = data->buffer;
+	fileIndex = HZ_SIM_FIRST_ZONE;										// Point to the first homezone data
+
+	for (hzIndex=0; hzIndex<HZ_ZONES_MAX; hzIndex++)					// For each homezone...
+	{
+		homezone[hzIndex].zoneID = simFile[fileIndex];				// Read in the various parameters
+		fileIndex++;
+		
+		homezone[hzIndex].X = readHexFromSimfile(&simFile[fileIndex],4);
+		fileIndex += 4;
+		homezone[hzIndex].Y = readHexFromSimfile(&simFile[fileIndex],4);
+		fileIndex += 4;
+		homezone[hzIndex].Rsquared = readHexFromSimfile(&simFile[fileIndex],4);
+		fileIndex += 4;
+		
+		homezone[hzIndex].active = (BOOL) (simFile[fileIndex] & HZ_ACTIVE_FLAG)/HZ_ACTIVE_FLAG;
+		homezone[hzIndex].cityzone = (BOOL) (simFile[fileIndex] & HZ_CITYZONE_FLAG)/HZ_CITYZONE_FLAG;
+		fileIndex++;
+					
+		/* Read in the 12-character tag name */
+		
+		for (tagIndex = 0; tagIndex<HZ_NAME_LENGTH; tagIndex++)					
+		{
+			character = (char) simFile[fileIndex];
+			fileIndex++;
+			if (character<32 || character>127)
+				character = 0;
+			homezone[hzIndex].Tag[tagIndex] = character;
+		}
+		homezone[hzIndex].Tag[HZ_NAME_LENGTH] = 0;								// Make sure tag is null-terminated
+
+#ifdef TRACE_MMIHOMEZONE
+			TRACE_EVENT_P1("Homezone %d:", hzIndex);
+			TRACE_EVENT_P1("ID: %d", homezone[hzIndex].zoneID);
+			TRACE_EVENT_P1("Active: %d", (UBYTE)homezone[hzIndex].active);
+			TRACE_EVENT_P1("Cityzone: %d", (UBYTE)homezone[hzIndex].cityzone);
+			TRACE_EVENT_P1("X: %X", homezone[hzIndex].X);
+			TRACE_EVENT_P1("Y: %X", homezone[hzIndex].Y);
+			TRACE_EVENT_P1("Rsquared: %X", homezone[hzIndex].Rsquared);
+		TRACE_EVENT_P1("Homezone name: %s", homezone[hzIndex].Tag);
+#endif
+
+	}
+
+	return;
+}
+
+
+/*******************************************************************************
+
+ $Function:    	homezoneWriteSim
+
+ $Description:	Write homezone data to the SIM
+				SPR 877 - SH - now just writes a single record
+ 
+ $Returns:		None.
+
+ $Arguments:	cache, record
+********************************************************************************/
+
+void homezoneWriteSim(USHORT field, USHORT record)
+{
+	T_homezone_data	*data				= &homezoneData;
+	USHORT hzIndex;
+	UBYTE *simFile;
+	USHORT fileIndex;
+
+	/* Check if homezone is already switched off */
+
+	if (data->received==HZ_RECEIVED_HZ_OFF)
+		return;
+	
+	TRACE_FUNCTION("homezoneWriteSim()");
+
+	hzIndex = field-HZ_SIM_CELL_CACHE;
+	
+#ifdef TRACE_MMIHOMEZONE
+	TRACE_EVENT_P4("HZ WRITE field: %X record %d lac %X cid %X", field, record, data->homezone[hzIndex].lac[record-1], data->homezone[hzIndex].cid[record-1]);
+#endif
+
+	if (data->homezone[hzIndex].active)
+	{	
+		simFile = data->buffer2;
+		fileIndex = 0;
+		writeHexToSimfile(&simFile[fileIndex], data->homezone[hzIndex].lac[record-1], 2 );
+		fileIndex += 2;
+		writeHexToSimfile(&simFile[fileIndex], data->homezone[hzIndex].cid[record-1], 2 );
+	}
+
+	if (!Write_Sim_Record(field, record, HZ_SIM_CELL_CACHE_SIZE, data->buffer2))
+	{
+		TRACE_EVENT("SIM writing error!");
+	}
+	return;
+}
+
+
+/*******************************************************************************
+
+ $Function:    	homezoneWriteSimCb
+
+ $Description:	Write homezone data to the SIM.  This function is called after a previous
+ 				SIM write (or, in the initial case, by homezoneWriteSim above).
+				SPR877 - SH - Previous functionality no longer required here.
+ 
+ $Returns:		None.
+
+ $Arguments:	field - the SIM field that is to be written
+ 				record - the SIM record that is to be written
+ 				result - the result of the last write attempt
+*******************************************************************************/
+
+void homezoneWriteSimCb(USHORT field, USHORT record, USHORT result)
+{
+	T_homezone_data	*data				= &homezoneData;
+	T_homezone		*homezone			= data->homezone;
+	USHORT			hzIndex;
+	UBYTE			*simFile;
+	USHORT			fileIndex;
+	UBYTE			keepLooking;
+
+	TRACE_FUNCTION("homezoneWriteSimCb()");
+
+#ifdef TRACE_MMIHOMEZONE
+	TRACE_EVENT_P1("RESULT: %d", result);
+#endif
+
+	return;
+}
+
+
+/*******************************************************************************
+
+ $Function:    	homezoneCBData
+
+ $Description:	Make sure correct homezone CB channel is set up and activate CB
+ 
+ $Returns:		None.
+
+ $Arguments:	message		- The text of the cell broadcast message
+*******************************************************************************/
+
+void homezoneActivateCB(void)
+{
+	T_homezone_data	*data				= &homezoneData;
+	USHORT index;
+	UBYTE stopSearch;
+	USHORT emptyID;
+
+	/* Check if homezone is already switched off */
+
+	if (data->received==HZ_RECEIVED_HZ_OFF)
+		return;
+	
+	TRACE_FUNCTION("homezoneActivateCB()");
+	
+	/* Check table to see if correct channel is included */
+	
+	stopSearch = FALSE;
+	emptyID = 0xFFFF;
+	
+	for (index=0; index<MAX_MIDS && !stopSearch; index++)
+	{
+		TRACE_EVENT_P2("Mid %d is %X", index, g_smscb_data.CBTopics.entry[index].msg_id);
+		if (g_smscb_data.CBTopics.entry[index].msg_id==HZ_IDENTIFIER)
+		{
+			stopSearch = TRUE;
+		}
+		else if (g_smscb_data.CBTopics.entry[index].msg_id==NO_MID)
+		{
+			emptyID = index;
+			stopSearch = TRUE;
+		}		
+	}
+
+	TRACE_EVENT_P1("Emtpy ID %d", emptyID);
+	
+	if (emptyID!=0xFFFF && emptyID<MAX_MIDS-1)
+	{
+		strncpy (g_smscb_data.CBTopics.entry[emptyID].name, HZ_CB_NAME, CB_TAG_LENGTH);
+	    g_smscb_data.CBTopics.entry[emptyID].msg_id = HZ_IDENTIFIER;
+	     g_smscb_data.CBTopics.entry[emptyID].dcs = 0;
+
+	    // add a new entry
+	    emptyID += 1;
+	    g_smscb_data.CBTopics.length = emptyID;
+	}
+	
+    smscb_setCBsettings(SMSCB_SWITCH_ON);
+	return;
+}
+
+
+/*******************************************************************************
+
+ $Function:    	homezoneCBData
+
+ $Description:	A cell broadcast message has been received, containing information about
+ 				the location of the current cell
+ 
+ $Returns:		None.
+
+ $Arguments:	message		- The text of the cell broadcast message
+*******************************************************************************/
+
+void homezoneCBData(char *message)
+{
+	T_homezone_data	*data				= &homezoneData;
+
+	/* Check if homezone is already switched off */
+
+	if (data->received==HZ_RECEIVED_HZ_OFF)
+		return;
+
+	TRACE_FUNCTION("homezoneCellData()");
+
+	/* Calculate the current position from the text of the message */
+	
+	data->current_X = calculateDecimal( &message[0], HZ_COORD_DIGITS );
+	data->current_Y = calculateDecimal( &message[HZ_COORD_DIGITS], HZ_COORD_DIGITS );
+
+#ifdef TRACE_MMIHOMEZONE
+	TRACE_EVENT_P2("current_X: %X, current_Y: %X", data->current_X, data->current_Y);
+#endif
+			
+	data->received |= HZ_RECEIVED_CB;				// We now have received cell broadcast message.
+
+	/* SPR877 - SH - now only call HZ algorithm if a cell res has recently taken place */
+	
+	if (data->received==HZ_RECEIVED_ALL && data->new_cell_res)  // If we've received everything, call algorithm.
+	{
+		homezoneLocate();
+		data->new_cell_res = FALSE;
+	}
+			
+ 	return;
+}
+
+
+/*******************************************************************************
+
+ $Function:    	homezoneLocate
+
+ $Description:	Looks at coordinates from cell broadcast message and calculates if
+ 				they are in a homezone
+ 
+ $Returns:		None
+
+ $Arguments:	None
+ 
+*******************************************************************************/
+
+void homezoneLocate()
+{
+	T_homezone_data	*data				= &homezoneData;
+	T_homezone		*homezone			= data->homezone;
+	long			deltaX;
+	long			deltaY;
+	USHORT			hzIndex;
+	USHORT			cacheIndex;
+	U32				Dsquared;
+	BOOL			foundInCache;
+	USHORT			cacheFreeSpace;	
+	USHORT			field;
+	USHORT			record;
+	//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+	//begin 30439
+	UBYTE           version;
+	USHORT          max_rcd;
+	EF_HZCACHE      cache;
+	UBYTE			exist = 0;
+	//end 30439
+
+	/* Check if homezone is already switched off */
+	
+	if (data->received==HZ_RECEIVED_HZ_OFF)
+		return;
+	
+	TRACE_FUNCTION("homezoneLocate()");
+
+	data->current_zone = HZ_NOT_IN_ZONE;							// We don't know if we're in a homezone yet (homezones = 0 to 3)
+	field = HZ_NOT_IN_ZONE;											// The cache to update
+
+	/* Work out if we're in a homezone using current_X and current_Y, received from CB message */
+
+	if (data->received == HZ_RECEIVED_ALL)
+	{
+#ifdef TRACE_MMIHOMEZONE
+		TRACE_EVENT_P2("Current cell X: %X, Y: %X", data->current_X,data->current_Y);
+#endif
+	
+		/* Check to see if (current_X,current_Y) is in any of the defined homezones */
+		
+		for (hzIndex=0; hzIndex<HZ_ZONES_MAX && data->current_zone==HZ_NOT_IN_ZONE; hzIndex++)						// For each homezone...
+		{
+#ifdef TRACE_MMIHOMEZONE		
+			TRACE_EVENT_P1("Homezone %d...", hzIndex);
+			TRACE_EVENT_P3("Has coords X: %X, Y: %X, R2: %X", homezone[hzIndex].X, homezone[hzIndex].Y, homezone[hzIndex].Rsquared);
+#endif
+
+			if (homezone[hzIndex].active)										// Provided the homezone is active
+			{
+#ifdef TRACE_MMIHOMEZONE														// Calculate X and Y distance 
+				TRACE_EVENT("Is active.");
+#endif
+				deltaX = labs(data->current_X-homezone[hzIndex].X);				// between centre of current cell
+				deltaY = labs(data->current_Y-homezone[hzIndex].Y);				// and centre of the homezone
+#ifdef TRACE_MMIHOMEZONE
+				TRACE_EVENT_P1("deltaX = %d",deltaX);
+				TRACE_EVENT_P1("deltaY = %d",deltaY);
+#endif		
+				if (deltaX<=HZ_DISTANCE_MAX && deltaY<=HZ_DISTANCE_MAX) 		// If not too far...
+				{
+					Dsquared = deltaX*deltaX+deltaY*deltaY;						// Calculate the resultant distance squared
+#ifdef TRACE_MMIHOMEZONE
+						TRACE_EVENT_P1("Dsquared = %d",Dsquared);
+#endif							
+					if (Dsquared <= homezone[hzIndex].Rsquared)					// If within radius of homezone squared
+					{
+#ifdef TRACE_MMIHOMEZONE
+						TRACE_EVENT("Contains the current cell.");
+#endif
+						data->current_zone = hzIndex;						// Current zone is this homezone
+						
+						if (!homezone[hzIndex].cityzone)							// Then: if it's not a cityzone
+						{
+#ifdef TRACE_MMIHOMEZONE
+							TRACE_EVENT("Is not a cityzone.");
+#endif
+							foundInCache = FALSE;									// Look through the cache for this
+							cacheFreeSpace = HZ_CACHE_MAX;							// homezone to see if cell is listed
+
+							for (cacheIndex=0; cacheIndex<HZ_CACHE_MAX && !foundInCache; cacheIndex++)
+							{
+								if (data->cid==homezone[hzIndex].cid[cacheIndex])
+								{
+									foundInCache = TRUE;							// We've found it!
+								}
+								if (homezone[hzIndex].cid[cacheIndex]==0 && cacheFreeSpace==HZ_CACHE_MAX)
+									cacheFreeSpace = cacheIndex;					// Or we've found an empty space
+							}
+
+							if (!foundInCache)										// If not there, need to add it
+							{
+#ifdef TRACE_MMIHOMEZONE
+								TRACE_EVENT("Is not in the cache.");
+#endif
+								if (cacheFreeSpace==HZ_CACHE_MAX)					// If we didn't find a free space...
+								{
+									cacheFreeSpace = rand() % HZ_CACHE_MAX;			// Choose a random entry 
+								}
+								homezone[hzIndex].cid[cacheFreeSpace] = data->cid;	// And store current cell there
+								homezone[hzIndex].lac[cacheFreeSpace] = data->lac;	// with its location area code
+
+								field = hzIndex+HZ_SIM_CELL_CACHE;					// We've changed the cache
+								record = cacheFreeSpace+1;
+
+#ifdef TRACE_MMIHOMEZONE
+								TRACE_EVENT_P1("Have added to cache, entry %d.",cacheFreeSpace);
+#endif
+							}
+						}
+					}
+					else															// If we're not in the homezone...
+					{
+						foundInCache = FALSE;										// Look through the cache for this
+																					// homezone to see if cell is listed
+						for (cacheIndex=0; cacheIndex<HZ_CACHE_MAX && !foundInCache; cacheIndex++)
+						{
+							if (data->cid==homezone[hzIndex].cid[cacheIndex])
+							{
+								foundInCache = TRUE;								// We've found it!
+								cacheFreeSpace = cacheIndex;						// Record where it is
+								break;
+							}
+						}
+
+						if (foundInCache)											// If it's there...
+						{
+#ifdef TRACE_MMIHOMEZONE
+							TRACE_EVENT("Is in the cache and shouldn't be.");
+#endif
+							homezone[hzIndex].cid[cacheFreeSpace] = 0;				// ...remove it
+							field = hzIndex+HZ_SIM_CELL_CACHE;					// We've changed the cache
+							record = cacheFreeSpace+1;
+							data->current_zone = HZ_NOT_IN_ZONE;						// We're not in this zone
+						}
+#ifdef TRACE_MMIHOMEZONE
+						else
+						{
+							TRACE_EVENT("Isn't in the cache and shouldn't be.");
+						}
+#endif
+					}
+
+					//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+					//begin 30439
+					/* check if the cid is already in cache */
+					for (cacheIndex=0; cacheIndex<HZ_CACHE_MAX; cacheIndex++)
+					{
+						if (data->recent_cell[cacheIndex] == data->cid)
+							exist = 1;
+					}
+					/* Replace oldest cell in dynamic cache with new cell */
+					//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+					//begin 30439
+					//Added a conditional statement
+					if (!exist)
+					{
+					data->recent_cell_index++;
+					if (data->recent_cell_index>=HZ_RECENT_MAX)
+						data->recent_cell_index = 0;
+#ifdef TRACE_MMIHOMEZONE
+					TRACE_EVENT_P1("Adding to recent list, index = %d", data->recent_cell_index);
+#endif
+					data->recent_cell[data->recent_cell_index] = data->cid;
+					data->recent_cell_zone[data->recent_cell_index] = data->current_zone;
+					
+					//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+					//begin 30439
+					/* write cache to PCM */
+					writeHexToSimfile(&cache.cid[0], data->recent_cell[data->recent_cell_index], 2 );
+					cache.zone = data->recent_cell_zone[data->recent_cell_index];
+					/* write cache to PCM */
+					pcm_WriteRecord((UBYTE *)EF_HZCACHE_ID,
+									(USHORT)(data->recent_cell_index+1),
+									SIZE_EF_HZCACHE,
+									&cache.cid[0]);
+
+					}
+					//end 30439
+#ifdef TRACE_MMIHOMEZONE
+for (cacheIndex = 0; cacheIndex<HZ_RECENT_MAX; cacheIndex++)
+{
+		TRACE_EVENT_P3("Recent cache %d: CID %X, zone %X",cacheIndex, data->recent_cell[cacheIndex], data->recent_cell_zone[cacheIndex]);
+}
+#endif
+				}
+
+			}
+
+		}
+
+	}
+
+#ifdef TRACE_MMIHOMEZONE
+	TRACE_EVENT("CACHES AFTER UPDATE");
+	for (hzIndex=0; hzIndex<HZ_ZONES_MAX; hzIndex++)			// For each homezone...
+	{	
+		TRACE_EVENT_P2("Zone %d (%s)", hzIndex, homezone[hzIndex].Tag);
+
+		if (homezone[hzIndex].active && !homezone[hzIndex].cityzone)				// If it's active, and not a cityzone
+		{
+			for (cacheIndex=0; cacheIndex<HZ_CACHE_MAX; cacheIndex++)	// Check the cache.
+			{ 
+				TRACE_EVENT_P3("Cache %d: lac %X, cid %X", cacheIndex, homezone[hzIndex].lac[cacheIndex], homezone[hzIndex].cid[cacheIndex]);
+			}
+		}
+	}
+#endif
+	/* Update icon/text tag. */
+	
+	homezoneUpdateDisplay();
+	
+	/* Write data back to SIM if cache has changed & SIM files present */
+
+	if (field!=HZ_NOT_IN_ZONE && (data->received & HZ_RECEIVED_SIMDATA))
+	{
+		homezoneWriteSim(field, record);
+	}
+	
+	return;
+}
+
+
+/*******************************************************************************
+
+ $Function:    	homezoneUpdate
+
+ $Description:	Main homezone function; check whether MS is in a homezone or not
+ 
+ $Returns:		
+
+ $Arguments:	lac		- the location area code of the current cell (on cell reselection)
+ 				cid	- the ID of the current cell (on cell reselection)
+				keep - 1: no change in lac and cid
+*******************************************************************************/
+//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+//begin 30439
+//Added an extra argument in the function -- "keep"
+void homezoneUpdate(USHORT lac, USHORT cid, UBYTE keep)
+{
+	T_homezone_data	*data				= &homezoneData;
+	T_homezone		*homezone			= data->homezone;
+	USHORT			hzIndex;
+	USHORT			cacheIndex;
+	UBYTE			cacheUpdate;
+	UBYTE			recordUpdate;
+	UBYTE			inCache = 0;
+
+	/* Check if homezone is already switched off */
+
+	TRACE_EVENT_P1("Data received: %d", data->received);
+	
+	if (data->received==HZ_RECEIVED_HZ_OFF)
+		return;
+	
+	TRACE_FUNCTION("homezoneUpdate()");
+
+	data->current_zone = HZ_NOT_IN_ZONE;							// We don't know if we're in a homezone yet (homezones = 0 to 3)
+	data->received |= HZ_RECEIVED_CELLRES;							// Have received this event
+	//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+	//Modified to add a conditional statement
+	//begin 30439
+	if (!keep)
+	{
+		data->lac = lac;
+		data->cid = cid;
+	}
+	/* keep the current lac and cid */
+	else
+	{
+		lac = data->lac;
+		cid = data->cid;
+	}
+	//end 30439
+
+#ifdef TRACE_MMIHOMEZONE
+	TRACE_EVENT_P3("lac: %X, cid: %X, received: %d", lac, cid, data->received);
+#endif
+
+	/* If either are zero or -1, the reselection data is invalid */
+	//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+	//Modified to add a conditional statement
+	if (((lac==0 || cid==0) || (lac==0xFFFF || cid==0xFFFF)) AND !keep)
+	{
+		TRACE_EVENT_P1("homezoneUpdateDisplay ~HZ_RECEIVED_CELLRES keep=%d", keep);
+	//end 30439
+		data->received &= (~HZ_RECEIVED_CELLRES);
+		homezoneUpdateDisplay();
+		return;
+	}
+
+	data->new_cell_res = TRUE;										// Cell res just occurred
+
+	/* Must have received SIM data to continue*/
+
+	if (!(data->received & HZ_RECEIVED_SIMDATA))
+		return;
+	
+	/* Check homezone cache for each homezone */
+	/* Can do this even if we haven't received the CB message */
+
+#ifdef TRACE_MMIHOMEZONE
+	TRACE_EVENT("Checking zone caches...");
+#endif
+	
+	for (hzIndex=0; hzIndex<HZ_ZONES_MAX && data->current_zone==HZ_NOT_IN_ZONE; hzIndex++)			// For each homezone...
+	{
+#ifdef TRACE_MMIHOMEZONE
+		TRACE_EVENT_P2("Zone %d (%s)", hzIndex, homezone[hzIndex].Tag);
+#endif
+		
+		if (homezone[hzIndex].active && !homezone[hzIndex].cityzone)				// If it's active, and not a cityzone
+		{
+#ifdef TRACE_MMIHOMEZONE
+		TRACE_EVENT("Is Active.");
+#endif		
+			for (cacheIndex=0; cacheIndex<HZ_CACHE_MAX && data->current_zone==HZ_NOT_IN_ZONE; cacheIndex++)	// Check the cache.
+			{ 
+#ifdef TRACE_MMIHOMEZONE
+					TRACE_EVENT_P3("Cache %d: lac %X, cid %X", cacheIndex, homezone[hzIndex].lac[cacheIndex], homezone[hzIndex].cid[cacheIndex]);
+#endif
+				
+				if (cid==homezone[hzIndex].cid[cacheIndex])					// If the current cell is in the cache....
+				{
+#ifdef TRACE_MMIHOMEZONE
+					TRACE_EVENT_P1("Cell found in cache %d.",cacheIndex);
+#endif
+					data->current_zone = hzIndex;									// Then this is our current homezone!
+					inCache = 1;
+				}
+			}
+			if (!inCache AND hzFlag)
+			{
+				hzFlag = 0;
+				TRACE_EVENT ("not in cache, caculate needed");
+				homezoneLocate();
+				return;
+			}
+			else
+				inCache = 0;
+		}
+	}
+	//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+	//added a conditional statement
+	//begin 30439
+	/* If we didn't find a homezone, check recent cells cache to see if we're in a cityzone */
+	for (hzIndex=0; hzIndex<HZ_ZONES_MAX && data->current_zone==HZ_NOT_IN_ZONE; hzIndex++)			// For each homezone...
+	{
+#ifdef TRACE_MMIHOMEZONE
+		TRACE_EVENT_P2("Zone %d (%s)", hzIndex, homezone[hzIndex].Tag);
+#endif
+		
+		if (homezone[hzIndex].active && homezone[hzIndex].cityzone)				// If it's active, and not a cityzone
+		{
+#ifdef TRACE_MMIHOMEZONE
+		TRACE_EVENT("Is Active.");
+#endif		
+		
+		for (cacheIndex=0; cacheIndex<HZ_RECENT_MAX && data->current_zone==HZ_NOT_IN_ZONE; cacheIndex++)	// Check the cache.
+		{ 
+#ifdef TRACE_MMIHOMEZONE
+				TRACE_EVENT_P5("Cache %d: lac %X, cid %X, data->recent_cell %X, data->recent_cell_zone %d", cacheIndex, homezone[hzIndex].lac[cacheIndex], homezone[hzIndex].cid[cacheIndex], data->recent_cell[cacheIndex], data->recent_cell_zone[cacheIndex]);
+#endif
+				
+			if (cid==data->recent_cell[cacheIndex] && data->recent_cell_zone[cacheIndex]!=HZ_NOT_IN_ZONE) // If we're in that cell 
+				{
+#ifdef TRACE_MMIHOMEZONE
+				TRACE_EVENT_P1("FOUND cityzone in cache %d.",cacheIndex);
+#endif
+				//Jun 14, 2005 REF: MMI-FIX-30439 x0018858
+				//Modified to directly assign value
+				data->current_zone = hzIndex;									// Then this is our current homezone!
+				inCache = 1;
+			}
+			if (!inCache AND hzFlag)
+			{
+				hzFlag = 0;
+				TRACE_EVENT ("not in cache, caculate needed");
+				homezoneLocate();
+				return;
+			}
+			else
+				inCache = 0;
+		}
+		}
+	}
+
+	homezoneUpdateDisplay();								// Update icon/text tag.
+
+	return;
+}
+
+
+/*******************************************************************************
+
+ $Function:    	homezoneUpdateDisplay
+
+ $Description:	
+ 
+ $Returns:		Updates the homezone icon and text string appropriately
+
+ $Arguments:	none
+*******************************************************************************/
+
+void homezoneUpdateDisplay(void)
+{
+	T_homezone_data	*data	= &homezoneData;
+
+	TRACE_FUNCTION("homezoneUpdateDisplay()");
+
+	iconsDeleteState(iconIdHomezone);
+	
+#ifdef FF_MMI_SAT_ICON
+	addSatMessage(NULL, 0, 0, NULL, FALSE, SAT_ICON_NONE);
+#else
+	addSatMessage(NULL);
+#endif
+	
+	if (data->current_zone!=HZ_NOT_IN_ZONE)										// If not in a homezone, leave blank
+	{
+//x0035544 Mar 14, 2006 DR:OMAPS00061468
+#ifdef FF_MMI_SAT_ICON
+	addSatMessage(data->homezone[data->current_zone].Tag, 0, 0, NULL, FALSE, SAT_ICON_NONE);
+#else
+	addSatMessage(data->homezone[data->current_zone].Tag);
+#endif
+		if (!data->homezone[data->current_zone].cityzone)						// Display icon if homezone rather than cityzone
+		{
+			iconsSetState(iconIdHomezone);
+		}
+	}
+	
+	return;
+}
+
+
+/*******************************************************************************
+
+ $Function:    	calculateDecimal
+
+ $Description:	
+ 
+ $Returns:		Returns a decimal number from a string of ascii digits
+
+ $Arguments:	none
+*******************************************************************************/
+
+static U32 calculateDecimal( char *string, int length )
+{
+	U32 total = 0;
+	int index;
+	
+	/* decode each decimal character in turn */
+	for (index = 0; index < length; index++ )
+	{
+		if (string[index]>='0' && string[index]<='9')
+		{
+			total = ( total * 10 ) + ( string[index] - '0' );
+		}
+	}
+	
+	return total;
+}
+
+/*******************************************************************************
+
+ $Function:    	readHexFromSimfile
+
+ $Description:	Reads a hex string (MSB first) from a sim file
+ 
+ $Returns:		The hex number
+
+ $Arguments:	simFile - the point in the simFile at which the string occurs
+ 				length  - the length of the string
+*******************************************************************************/
+
+static U32 readHexFromSimfile( UBYTE *simFile, int length )
+{
+	U32 total = 0;
+	int index;
+	
+	for ( index = 0; index < length; index++ )
+	{
+		total = ( total << 8 ) + simFile[index];
+	}
+  
+	return total;
+}
+
+/*******************************************************************************
+
+ $Function:    	writeHexToSimfile
+
+ $Description:	Writes a hex string (MSB first) to a sim file
+ 
+ $Returns:		None
+
+ $Arguments:	simFile - the point in the simFile at which the string occurs
+ 				length  - the length of the string
+*******************************************************************************/
+
+static void writeHexToSimfile( UBYTE *simFile, U32 value, int length )
+{
+	int index;
+
+#ifdef TRACE_MMIHOMEZONE
+	TRACE_EVENT_P1("Hex of %X is:", value);
+#endif
+
+	/* Note: '-1' below clarification:
+	 * E.g. index=0, length=4: most significant byte is number shifted 3 bytes right. */
+	 
+	for ( index = 0; index < length; index++ )
+	{
+		simFile[index] = (value >> ((length-index-1)*8)) & 0xFF;	/* SPR877 - SH - wrong before, added *8 */
+#ifdef TRACE_MMIHOMEZONE
+		TRACE_EVENT_P2("Simfile %d is %X", index,  simFile[index]);
+#endif
+	}
+  
+	return;
+}