view src/aci2/bmi/ATBWapAUI.c @ 662:8cd8fd15a095

SIM speed enhancement re-enabled and made configurable TI's original code supported SIM speed enhancement, but Openmoko had it disabled, and OM's disabling of speed enhancement somehow caused certain SIM cards to start working which didn't work before (OM's bug #666). Because our FC community is much smaller in year 2020 than OM's community was in their day, we are not able to find one of those #666-affected SIMs, thus the real issue they had encountered remains elusive. Thus our solution is to re-enable SIM speed enhancement and simply wait for if and when someone runs into a #666-affected SIM once again. We provide a SIM_allow_speed_enhancement global variable that allows SIM speed enhancement to be enabled or disabled per session, and an /etc/SIM_spenh file in FFS that allows it to enabled or disabled on a non-volatile basis. SIM speed enhancement is now enabled by default.
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 24 May 2020 05:02:28 +0000
parents 93999a60b835
children
line wrap: on
line source

/*******************************************************************************

					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:
 $Project code:
 $Module:
 $File:		    ATBWapAUI.c
 $Revision:

 $Author:		Condat(UK)
 $Date:

********************************************************************************

 Description:
 	Provides most of the functionality of the ATB, as well as an interface with the AUI.


********************************************************************************

 $History: ATBWapAUI.c
 
    Sep 06 2005  REF:  MMI-SPR-34048  x0012849, Jagan
    Description :  GIF is displayed as  ?
    Solution:  Close the decoder  once for each open
 	xreddymn Aug-03-2005 MMI-SPR-33058:
    Handling of animated GIF images with transparency
 
    xreddymn Jun-29-2005 MMI-ENH-32467:
    Handling of animated GIF images

    xrashmic 29 Jun, 2005 MMI-SPR-32462
    Patch given by Kyle for display of table border
 
    xreddymn Jun-21-2005 MMI-SPR-30291: Send one message for the entire profile,
    instead of sending one parameter at a time, to the WAP adapter
 
	Jun-08-2005 MMI-SPR-30291 xreddymn: Added patches from FG

       May 11 2005  REF:  MMI-SPR-29887  x0012849
       To Implement the deferred MMS retrieval.
       
      Apr 28 2005  REF:  MMI-SPR-30400  x0012849
      To display the contents of Drop down menu correctly when a page is browsed through  D sample.

	xreddymn Mar-22-2005 MMI-SPR-29767
	Modified behaviour of SL push message handling in MMI

       xrashmic 08 Feb, 2005 MMI-SPR-27853
       Error handling in sending MMS and also displaying the progress  value
       
    Jan-24-2005 MMI-SPR-28135 - xreddymn: WAP_OTA settings saved in WAP profiles

       xrashmic 21 Jan, 2005 MMI-SPR-28223
       When a plugin image is displayed, we ignore the scroll key events

       xrashmic 28 Jan, 2005 MMI-SPR-28166
       Adding support for saving plugin images

	xreddymn Jan-06-2005 MMI-SPR-27618:
	Added end of string character to terminate strings in ATB_wap_entry_add

	xrashmic 16 Dec, 2004 MMI-SPR-27622
	To add support for deleting and adding Profiles

	Dec-10-2003 MMI-SPR-26159 - xreddymn: Prevent duplicate entries in History List

	15/05/2003 - SPR#1983 - SH - Updated to latest from 1.6.3 version.

 $End

*******************************************************************************/
#ifndef MFW
#define MFW
#endif

#ifdef MFW
#define ENTITY_MFW
#else
#ifdef SMI
#define ENTITY_SMI
#else
#define ENTITY_ACI
#endif
#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "typedefs.h"

/* BEGIN ADD: Sumit : Req ID: : 31-Mar-2005*/
#ifndef NEPTUNE_BOARD
/* END ADD: Sumit : Req ID: : 31-Mar-2005*/
#include "ffs/ffs.h"
/* BEGIN ADD: Sumit : Req ID: : 31-Mar-2005*/
#else
#include "ffs.h"
#endif
/* END ADD: Sumit : Req ID: : 31-Mar-2005*/

#include "MmiWapFfs.h"
#ifdef FF_GPF_TCPIP
#include "leconfig.h"
#include "capimic.h"
#include "aapimic.h"
#include "wapmic_types.h"
//kyle 29 Jun, 2005 MMI-SPR-32462
#include "tapimmi.h"
#else
#include "gledef.h"
#include "capiclnt.h"
#include "aapiclnt.h"
#include "wap_types.h"
#endif


#include "ATBWapACI.h"
#include "ATBData.h"
#include "ATBWapAUI.h"
#include "font_bitmaps.h"

#include "cus_aci.h"
#include "prim.h"
#ifndef PCM_2_FFS
#include "pcm.h"
#endif
#include "dspl.h"
#ifdef FF_GPF_TCPIP
#include "mfw_sms.h"
#endif

void long_IP_to_char_IP(ULONG IPs,char* IPd);
#define DEFAULT_PROFILE 0		/* The default starting profile */

static T_WAP_VIEW		*View_header = 0;		/* View header points to first element in the view chain */
static T_WAP_VIEW		*Current_view = 0;		/* Points to the current view */

#if defined (FF_MMI_MMS) && defined (FF_GPF_TCPIP)
// May 11 2005  REF:  MMI-SPR-29887  x0012849
// MmsRetrievalType is used while Reading or writing Data from flash regarding retrieval type.
extern FlashDataMmsRetrievalType *MmsRetrievalType; 
//xrashmic 19 Aug, 2004 Bug: 2, 3, 36 and 42
extern int MMSactive;
//xrashmic 08 Feb, 2005 MMI-SPR-27853
extern void AUI_mms_status_notify(int status);

#endif

#ifdef FF_GPF_TCPIP
 // Apr 28 2005  REF:  MMI-SPR-30400 x0012849
 //This is added to see that check box is inline with the text.
 #define OFFSET_CHECKBOX 4
//xrashmic 21 Jan, 2005 MMI-SPR-28223
extern BOOL pluginImageDisplayed;

// xreddymn Jan-25-2005 MMI-SPR-28135: WAP_OTA
#include "mfw_ss.h" // For definitions of MFW_ASCII, MFW_DCS_UCS2
int 	ATB_convert_String(			char * ipString,	UBYTE ipDataType,	int ipLength,
									char * opString, 	UBYTE opDataType,	int opLength, UBYTE addNull);
extern void AUI_profile_list_redraw(S32 index);

#endif

/* LOCAL FUNCTION PROTOTYPES */

static void ATB_wap_buffer_image_scale(T_WAP_MMI_SEND_IMAGE_IND *image);
static void ATB_wap_buffer_text_draw(T_WAP_MMI_SEND_TEXT_IND *parameter);
static void ATB_wap_buffer_table_draw(T_WAP_MMI_SEND_TABLE_IND *parameter);
static void ATB_wap_buffer_line_draw(SHORT x1, SHORT y1, SHORT x2, SHORT y2);
static BOOL ATB_wap_buffer_onscreen(SHORT x, SHORT y, SHORT *deltaX, SHORT *deltaY);
static void ATB_wap_buffer_image_display(T_WAP_MMI_SEND_IMAGE_IND *image);

#if defined(TRACE_ATBWAPAUI) || defined(TRACE_ATBWAPACI)

/* Functions to display strings, for tracing purposes.
 * SPR#1437 - SH - Fixed these so they won't overwrite array bounds */

void ATB_trace_string(char *String, USHORT length)
{
	UBYTE stringIndex;
	UBYTE trace_string[41];

	for (stringIndex=0; (stringIndex<40 && stringIndex<length); stringIndex++)
		trace_string[stringIndex] = String[stringIndex];

	trace_string[stringIndex] = 0;

	TRACE_EVENT_P2("%s (%d)", trace_string, length);

	return;
}

void ATB_trace_ushort_string(USHORT *String, USHORT length)
{
	USHORT stringIndex;
	UBYTE trace_string[41];

	for (stringIndex=0; (stringIndex<40 && stringIndex<length); stringIndex++)
		trace_string[stringIndex] = (char) String[stringIndex];

	trace_string[stringIndex] = 0;

	TRACE_EVENT_P2("%s (%d)", trace_string, length);

	return;
}

#endif


/*******************************************************************************

 $Function:    	ATB_wap_start

 $Description:	Starts the WAP application and initialises the view chain

 $Returns:		None.

 $Arguments:	parameter		- dummy empty parameter

*******************************************************************************/

#ifdef CO_UDP_IP
void ATB_wap_start(T_MMI_WAP_START_IND *parameter)
#else
void ATB_wap_start(T_MMI_WAP_START_USER_AGENT_REQ *parameter)
#endif
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_start");
#endif

	M_MMI_WAP_START_IND(parameter);

	/* Initialise the pointer to the view chain */

	View_header = NULL;
	Current_view = NULL;

	return;
}

#if defined (FF_MMI_MMS) && defined (FF_GPF_TCPIP)
//TISHMMS Project
/*******************************************************************************

 $Function:    	ATB_mms_init_wap_data

 $Description:	init WapData and WapProfilesData

 $Returns:

 $Arguments:	parameter

*******************************************************************************/
void ATB_mms_init_wap_data(void)
{

#ifdef TRACE_ATBWAPAUI
    //TRACE_FUNCTION("ATB_mms_init_wap_data");
#endif

    if (WapData == NULL)
    {
        WapData = (FlashDataWap *) AUI_wap_memory_alloc(sizeof(FlashDataWap));      // Allocate memory for flash data
    }

    if (WapProfilesData == NULL)
    {
        WapProfilesData = (FlashDataWapProfiles *) AUI_wap_memory_alloc(sizeof(FlashDataWapProfiles));        // Allocate memory for profiles data
    }

    /* read FFS file to get WapData */
    if (flash_wap_read() == 0)
    {
        ATB_wap_profile_default_create();
    }

    return;
}

void ATB_mms_init_mms_data(void)
{
    // May 11 2005  REF:  MMI-SPR-29887  x0012849
    // type will hold the current retrieval condition
    BOOL Type; 
    if (MmsProfilesData == NULL)
    {
        MmsProfilesData = (FlashDataMmsProfiles *) AUI_wap_memory_alloc(sizeof(FlashDataMmsProfiles));        // Allocate memory for profiles data
    }
    // May 11 2005  REF:  MMI-SPR-29887  x0012849
    // Allocate memory for the MmsRetrievalType    
    // The memory allocated here freed in the function ATB_mms_free_wap_data
    if ( NULL == MmsRetrievalType)   
    {
        MmsRetrievalType = (FlashDataMmsRetrievalType *) AUI_wap_memory_alloc(sizeof(FlashDataMmsRetrievalType));       
    }	

    /* read FFS file to get WapData */
    if (flash_mms_read() == 0)
    {
        ATB_mms_profile_default_create();
    }
    // May 11 2005  REF:  MMI-SPR-29887  x0012849
    //If the Information is stored on flash then do nothing, other wise create a file on Flash
    // Initially MMS retrieval type is set to Immediate Retrieval.
   if(flash_mms_retrieval_type_read(&Type)==0)
   {
      flash_mms_retrieval_type_write(0);  // passed 0 indicates immediate
   }   
    return;
}


/*******************************************************************************

 $Function:    	ATB_mms_free_wap_data

 $Description:	free WapData

 $Returns:

 $Arguments:	parameter

*******************************************************************************/
void ATB_mms_free_wap_data(void)
{

#ifdef TRACE_ATBWAPAUI
	//TRACE_FUNCTION("ATB_mms_free_wap_data");
#endif

    if (WapData)
    {
        AUI_wap_memory_free ((UBYTE *)WapData, sizeof(FlashDataWap));
        WapData = NULL;
    }

    if (WapProfilesData)
    {
        AUI_wap_memory_free ((UBYTE *)WapProfilesData, sizeof(FlashDataWapProfiles));
        WapProfilesData = NULL;
    }

    if (MmsProfilesData)
    {
        AUI_wap_memory_free ((UBYTE *)MmsProfilesData, sizeof(FlashDataMmsProfiles));
        MmsProfilesData = NULL;
    }
   // May 11 2005  REF:  MMI-SPR-29887  x0012849
   // Memory is freed here for the MmsProfilesData
    if (MmsRetrievalType)
    {
        AUI_wap_memory_free ((UBYTE *)MmsRetrievalType, sizeof(FlashDataMmsRetrievalType ));
        MmsRetrievalType = NULL;
    }	

    return;
}/* end of ATB_mms_free_wap_data */


char* ATB_mms_get_MmscAddress(void)
{
    UBYTE ucProfileId;
    char* MmscAddress;

    ucProfileId = WapData->ProfileId;

    MmscAddress = MmsProfilesData->Profile[ucProfileId].MmscAddress;

    return MmscAddress;
}

void ATB_mms_get_wap_Profile(void ** MmsWapProfile)
{
    UBYTE			ucProfileId;

    char            TraceBuffer[100];

    T_WAP_PROFILE *  pTemp;


    ucProfileId = WapData->ProfileId;

    sprintf(TraceBuffer, "ATB_mms_get_wap_grofile called!ucProfileId = ");
    //M4_DebugStringMessage( TraceBuffer,(strlen(TraceBuffer)), ucProfileId);

    *MmsWapProfile = (void*)(&(WapProfilesData->Profile[ucProfileId]));

    pTemp = &(WapProfilesData->Profile[ucProfileId]);

    return;
}

void ATB_mms_profile_save(void)
{
	flash_mms_write();

	return;
}

//TISHMMS Project
//modification end
#endif
/*******************************************************************************

 $Function:    	ATB_wap_new_view

 $Description:	Starts a new view, defining the graphical size of the screen to
 				be handled.

 $Returns:		Pointer to the data structure of the new view

 $Arguments:	parameter		- width and height of the WAP view, etc.
 				UIdata			- Optional generic pointer, for use by the AUI.  This
 								can point to window information, etc, but is not used
 								by ATB.

*******************************************************************************/
#ifdef FF_GPF_TCPIP
T_WAP_VIEW* ATB_wap_new_view(T_MMI_WAP_NEW_VIEW_IND *parameter, void* UIdata)
{
	T_WAP_VIEW	*View	= (T_WAP_VIEW *) AUI_wap_memory_alloc (sizeof(T_WAP_VIEW));	// Create the view
	T_WAP_VIEW *ViewIndex;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_new_view");
#endif

	/* SPR#2086 - SH - Changes to allow for multiple views */

	View->URL	= (char *)AUI_wap_memory_alloc ((URL_MAX_LEN+1)*sizeof(char));
	/* SPR#1816 - SH - Card title is unicode */
	View->Title			= (USHORT *)AUI_wap_memory_alloc ((CARD_TITLE_MAX_LEN+1)*sizeof(USHORT)); // Title of card
	View->cardWidth		= WAP_SCREEN_WIDTH;
	View->cardHeight	= WAP_SCREEN_HEIGHT;
	/* SPR#1816 - SH - Profiles list is unicode */
	View->ProfilesList	= ATB_wap_entry_list_create(WAP_PROFILES_LIST, MAX_PROFILES, PROFILENAME_MAX_LEN, TRUE); // ...profiles names list
	View->object_id		= parameter->object_id;
	View->channel		= WAP_CHANNEL_ID;
	View->UIdata		= UIdata;
	View->ElementHeader	= NULL;					/* Element chain is as yet empty */
	View->NextView		= NULL;
	View->browser_status = ATB_WAP_NO_STATUS;	/* SPR#1547 - SH - Replaced 'status' with 'browser_status' */
	View->CustSoftKeys	= FALSE;				/* Whether we have customised soft keys */

	/* SPR#1816 - SH - Create entry lists.  Now with unicode parameter */

	View->Bookmarks		= ATB_wap_entry_list_create(WAP_BOOKMARKS_LIST, MAX_BOOKMARKS, CARD_TITLE_MAX_LEN, TRUE);
	View->BookmarksURL	= ATB_wap_entry_list_create(WAP_URL_LIST, MAX_BOOKMARKS, URL_MAX_LEN, FALSE);
	View->History		= ATB_wap_entry_list_create(WAP_HISTORY_LIST, MAX_HISTORY, CARD_TITLE_MAX_LEN+NUMBER_PADDING, TRUE);
	View->HistoryURL	= ATB_wap_entry_list_create(WAP_URL_LIST, MAX_HISTORY, URL_MAX_LEN, FALSE);
	View->cId			= -1;

	/* Check if WAP data exists */

	if (!WapData)
	{
		WapData = (FlashDataWap *) AUI_wap_memory_alloc(sizeof(FlashDataWap));		// Allocate memory for flash data
		WapProfilesData  = (FlashDataWapProfiles *) AUI_wap_memory_alloc(sizeof(FlashDataWapProfiles));		// Allocate memory for profiles data

		/* Default values are provided.  If either of the files 'mmi/wapdata'
		 * or 'mmi/wapprof' aren't found, files are created with these defaults.
		 * The '0' size indicator indicates that one of the files was not present. */

		if (flash_wap_read() == 0)
		{
			ATB_wap_profile_default_create();
		}
	}

	View->ProfileId		= WapData->ProfileId;								// Default starting profile								// Read in the current profile

	if (View_header == NULL)
		View_header = View;														// This is the first entry
	else
	{
		ViewIndex = View_header;
		while (ViewIndex->NextView != NULL)										// If not the last entry,
			ViewIndex = ViewIndex->NextView;									// find the next entry!
		ViewIndex->NextView = View;												// New entry is last entry in chain
	}

	Current_view = View;
	ATB_wap_profile_names_read(View);
	ATB_wap_profile_read(View, View->ProfileId);

	M_MMI_WAP_NEW_VIEW_IND(parameter);

	return View;
}

#else /* #ifdef FF_GPF_TCPIP */

T_WAP_VIEW* ATB_wap_new_view(T_MMI_WAP_NEW_VIEW_IND *parameter, void* UIdata)
{
	T_WAP_VIEW	*View;
	T_WAP_VIEW *ViewIndex;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_new_view");
#endif

	/* Create the view */

	View = (T_WAP_VIEW *) AUI_wap_memory_alloc (sizeof(T_WAP_VIEW));

	/* Allocate memory for two FFS files */

	WapData = (FlashDataWap *) AUI_wap_memory_alloc(sizeof(FlashDataWap));
	WapProfilesData  = (FlashDataWapProfiles *) AUI_wap_memory_alloc(sizeof(FlashDataWapProfiles));

	/* Allocate some arrays and lists */

	View->URL	= (char *)AUI_wap_memory_alloc ((URL_MAX_LEN+1)*sizeof(char));
	View->Title	= (USHORT *)AUI_wap_memory_alloc ((CARD_TITLE_MAX_LEN+1)*sizeof(USHORT));

	/* Set up some default values */

	View->cardWidth		= WAP_SCREEN_WIDTH;
	View->cardHeight	= WAP_SCREEN_HEIGHT;
	View->object_id		= parameter->object_id;
	View->channel		= WAP_CHANNEL_ID;
	View->UIdata		= UIdata;
	View->ElementHeader	= NULL;					/* Element chain is as yet empty */
	View->NextView		= NULL;
	View->browser_status = ATB_WAP_NO_STATUS;	/* Browser status is idle */
	View->CustSoftKeys	= FALSE;				/* Whether we have customised soft keys */
	View->cId			= -1;

	/* Create entry lists */

	View->ProfilesList	= ATB_wap_entry_list_create(WAP_PROFILES_LIST, MAX_PROFILES, PROFILENAME_MAX_LEN, TRUE);
	View->Bookmarks		= ATB_wap_entry_list_create(WAP_BOOKMARKS_LIST, MAX_BOOKMARKS, CARD_TITLE_MAX_LEN, TRUE);
	View->BookmarksURL	= ATB_wap_entry_list_create(WAP_URL_LIST, MAX_BOOKMARKS, URL_MAX_LEN, FALSE);
	View->History		= ATB_wap_entry_list_create(WAP_HISTORY_LIST, MAX_HISTORY, CARD_TITLE_MAX_LEN+NUMBER_PADDING, TRUE);
	View->HistoryURL	= ATB_wap_entry_list_create(WAP_URL_LIST, MAX_HISTORY, URL_MAX_LEN, FALSE);

	/* Read in profile information from flash */

	ATB_wap_profile_names_read(View);
	ATB_wap_profile_read(View, View->ProfileId);
	/* Add this view to the view chain */

	if (View_header == NULL)
		View_header = View;			/* This is the first entry */
	else
	{
		ViewIndex = View_header;
		while (ViewIndex->NextView != NULL)			/* If not the last entry, */
			ViewIndex = ViewIndex->NextView;		/* find the next entry! */
		ViewIndex->NextView = View;					/* New entry is last entry in chain */
	}

	Current_view = View;

	/* Tell WAP Browser to create new view */

	M_MMI_WAP_NEW_VIEW_IND(parameter);

	return View;
}

#endif  /* !#ifdef FF_GPF_TCPIP */

#ifdef FF_GPF_TCPIP
/*******************************************************************************

 $Function:    	ATB_wap_new_view_invisible

 $Description:	Starts a new view that is not associated with a browser
 				SPR#2086 - SH - Added

 $Returns:		Pointer to the data structure of the new view

 $Arguments:	object_id	- The object_id of the new view

*******************************************************************************/

T_WAP_VIEW* ATB_wap_new_view_invisible(UBYTE object_id)
{
	T_WAP_VIEW	*View	= (T_WAP_VIEW *) AUI_wap_memory_alloc (sizeof(T_WAP_VIEW));	// Create the view
	T_WAP_VIEW *ViewIndex;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_new_view_invisible");
#endif

	memset((void *)View, 0, sizeof(T_WAP_VIEW));

	/* Check if WAP data exists */

	if (!WapData)
	{
		WapData = (FlashDataWap *) AUI_wap_memory_alloc(sizeof(FlashDataWap));		// Allocate memory for flash data
		WapProfilesData  = (FlashDataWapProfiles *) AUI_wap_memory_alloc(sizeof(FlashDataWapProfiles));		// Allocate memory for profiles data

		/* Default values are provided.  If either of the files 'mmi/wapdata'
		 * or 'mmi/wapprof' aren't found, files are created with these defaults.
		 * The '0' size indicator indicates that one of the files was not present. */

		if (flash_wap_read() == 0)
		{
			ATB_wap_profile_default_create();
		}
	}

	View->ProfileId		= WapData->ProfileId;								// Default starting profile
	View->object_id		= object_id;
	View->channel		= WAP_CHANNEL_ID;
	View->browser_status = ATB_WAP_NO_STATUS;
	View->cId			= -1;
	View->Title			= (USHORT *)AUI_wap_memory_alloc ((CARD_TITLE_MAX_LEN+1)*sizeof(USHORT)); // Title of card


	if (View_header == NULL)
		View_header = View;			/* This is the first entry */
	else
	{
		ViewIndex = View_header;
		while (ViewIndex->NextView != NULL)			/* If not the last entry, */
			ViewIndex = ViewIndex->NextView;		/* find the next entry! */
		ViewIndex->NextView = View;					/* New entry is last entry in chain */
	}

	Current_view = View;

	ATB_wap_profile_read(View, View->ProfileId);								// Read in the current profile

	return View;
}

#endif


/*******************************************************************************

 $Function:    	ATB_wap_get_view

 $Description:	Returns a pointer to a view, given its object_id

 $Returns:		Pointer to the data structure of the specified view, or NULL if not found

 $Arguments:	object_id  - the id of the view

*******************************************************************************/

T_WAP_VIEW* ATB_wap_get_view(UBYTE object_id)
{
	T_WAP_VIEW *View = View_header;
	UBYTE Index;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_get_view()");
#endif

	if (!View_header)
	{
		return NULL;
	}

	/* SPR#1497 - SH - If object_id is 0, any view will do */

	if (object_id==0)
		return View;

	/* Search for object_id */

	for (Index = 0; View!=NULL && View->object_id!=object_id; Index++)
	{
		View = View->NextView;
	}

	return View;
}


#ifdef FF_GPF_TCPIP
/*******************************************************************************

 $Function:    	ATB_wap_change_view

 $Description:	Change the view to the one specified
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	object_id - The identifier for the view

*******************************************************************************/

void ATB_wap_change_view(UBYTE object_id)
{
	T_WAP_VIEW *View;

	TRACE_FUNCTION("ATB_wap_change_view()");

	if (!(View = ATB_wap_get_view(object_id)))
		return;

	Current_view = View;
	AUI_wap_view_changed(View);

	return;
}

#endif
/*******************************************************************************

 $Function:    	ATB_wap_destroy

 $Description:	Destroys any open view.  If no views are open, destroys the WAP
 				application by calling ATB_wap_terminate().

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	None.


*******************************************************************************/

#ifdef FF_GPF_TCPIP
T_WAP_RES ATB_wap_destroy()
{
	T_MMI_WAP_CLOSE_VIEW_IND		parameter1;
	static T_MMI_WAP_TERMINATE_IND	parameter2;
	T_WAP_VIEW						*ViewIndex;
	T_WAP_VIEW						*PrevView;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_destroy");
#endif
	/* Destroys an open view each time it is called.
	 * if there are no open views, the WAP browser is terminated. */

	/* Destroy the view chain.
 	 * If views still exist, destroy the bottom one */

	if (Current_view!=NULL)			/*Until end of chain */
	{
		ViewIndex = View_header;
		PrevView = NULL;

		/* Find the next view, or go to the view header */

		while (ViewIndex!=Current_view && ViewIndex!=NULL)
		{
			PrevView = ViewIndex;
			ViewIndex = ViewIndex->NextView;
		}

		TRACE_EVENT_P2("Found current view as %X; previous view = %X", ViewIndex, PrevView);

		if (ViewIndex==NULL)
		{
			TRACE_EVENT("**ERROR - cannot destroy view***");
			return;
		}

		/* If we're at the view header, then there is no previous view */

		if (ViewIndex==View_header)
		{
			View_header = View_header->NextView;
			Current_view = View_header;
		}
		else
		{
			Current_view = PrevView;
			Current_view->NextView = ViewIndex->NextView;	/* Close gap in view chain */
		}

		TRACE_EVENT_P1("Current view is now %X", Current_view);

		/* Notify MMI of new view */

		AUI_wap_view_changed(Current_view);

		parameter1.object_id = ViewIndex->object_id;

		ATB_wap_entry_list_destroy(ViewIndex->ProfilesList);					// Destroy profiles names list
		ATB_wap_entry_list_destroy(ViewIndex->Bookmarks);						// Destroy bookmarks
		ATB_wap_entry_list_destroy(ViewIndex->BookmarksURL);
		ATB_wap_entry_list_destroy(ViewIndex->History);							// Destroy history list
		ATB_wap_entry_list_destroy(ViewIndex->HistoryURL);

		/* SPR#2086 - SH - Only delete memory that has been allocated */

		if (ViewIndex->URL)
		{
			AUI_wap_memory_free ((UBYTE *)ViewIndex->URL, (URL_MAX_LEN+1)*sizeof(char)); // Delete URL string
		}

		if (ViewIndex->Title)
		{
			/* SPR#1816 - SH - Title is unicode */
			AUI_wap_memory_free ((UBYTE *)ViewIndex->Title, (CARD_TITLE_MAX_LEN+1)*sizeof(USHORT));   // Delete card title
		}

		if (ViewIndex->ElementHeader)
		{
			ATB_wap_buffer_clear(ViewIndex);										// Clear the element buffer
			ViewIndex->ElementHeader = ViewIndex->NewElementHeader;					// Just in case a new card is being created
			ATB_wap_buffer_clear(ViewIndex);										// Clear this too!
		}

		TRACE_EVENT_P1("Destroying view %X", ViewIndex);

		AUI_wap_memory_free((UBYTE *)ViewIndex, sizeof(T_WAP_VIEW));			// Destroy the current entry

		/* If the view is associated with a user agent, close that too */

		if (parameter1.object_id<WAP_DOWNLOAD_VIEW)
		{
			M_MMI_WAP_CLOSE_VIEW_IND(&parameter1);
		}
		/* Otherwise, indicate this view is closed */

		else
		{
			ATB_wap_close_view_done();
		}

		return WAP_OK;
	}

	else
	{
		/* SPR#1794 - SH - WAP data now split between two FFS files */
		/* Destroy the RAM copy of the FFS data */

		if (WapData)
		{
			AUI_wap_memory_free ((UBYTE *)WapData, sizeof(FlashDataWap));
			WapData = NULL;
		}

		/* Destroy the RAM copy of the FFS profiles information */

		if (WapProfilesData)
		{
			AUI_wap_memory_free ((UBYTE *)WapProfilesData, sizeof(FlashDataWapProfiles));
			WapProfilesData = NULL;
		}

		View_header = NULL;
		Current_view = NULL;

		/* Shut down WAP Browser */

		return ATB_wap_terminate(&parameter2);
	}
}

#else /* #ifdef FF_GPF_TCPIP */

T_WAP_RES ATB_wap_destroy()
{
	T_MMI_WAP_CLOSE_VIEW_IND		parameter1;
	static T_MMI_WAP_TERMINATE_IND	parameter2;
	T_WAP_VIEW						*ViewIndex;
	T_WAP_VIEW						*NextView;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_destroy");
#endif

	/* Destroy the view chain.
 	 * If views still exist, destroy the bottom one */

	if (View_header!=NULL)								/* Until end of chain */
	{
		ViewIndex = View_header;						/* Store the current entry pointer */
		View_header = ViewIndex->NextView;				/* Find the next entry */

		parameter1.object_id = ViewIndex->object_id;

		/* Destroy entry lists */

		ATB_wap_entry_list_destroy(ViewIndex->ProfilesList);
		ATB_wap_entry_list_destroy(ViewIndex->Bookmarks);
		ATB_wap_entry_list_destroy(ViewIndex->BookmarksURL);
		ATB_wap_entry_list_destroy(ViewIndex->History);
		ATB_wap_entry_list_destroy(ViewIndex->HistoryURL);

		/* Free strings */

		AUI_wap_memory_free ((UBYTE *)ViewIndex->URL, (URL_MAX_LEN+1)*sizeof(char));
		AUI_wap_memory_free ((UBYTE *)ViewIndex->Title, (CARD_TITLE_MAX_LEN+1)*sizeof(USHORT));

		/* Clear the element buffer */

		ATB_wap_buffer_clear(ViewIndex);

		/* If a new card is being created, clear this too */

		ViewIndex->ElementHeader = ViewIndex->NewElementHeader;
		ATB_wap_buffer_clear(ViewIndex);

		/* Free View memory */

		AUI_wap_memory_free((UBYTE *)ViewIndex, sizeof(T_WAP_VIEW));

		/* Tell WAP Browser to close the view */

		M_MMI_WAP_CLOSE_VIEW_IND(&parameter1);

		return WAP_OK;
	}

	else
	{
		/* Destroy the RAM copy of the FFS data */

		if (WapData)
		{
			AUI_wap_memory_free ((UBYTE *)WapData, sizeof(FlashDataWap));
			WapData = NULL;
		}

		/* Destroy the RAM copy of the FFS profiles information */

		if (WapProfilesData)
		{
			AUI_wap_memory_free ((UBYTE *)WapProfilesData, sizeof(FlashDataWapProfiles));
			WapProfilesData = NULL;
		}

		View_header = NULL;
		Current_view = NULL;

		/* Shut down WAP Browser */

		return ATB_wap_terminate(&parameter2);
	}
}

#endif /* !#ifdef FF_GPF_TCPIP */

/*******************************************************************************

 $Function:    	ATB_wap_UIdata

 $Description:	Returns the UI pointer, for use by AUI

 $Returns:		The void pointer

 $Arguments:	None.

*******************************************************************************/

void * ATB_wap_UIdata()
{
	if (View_header)
		return View_header->UIdata;
	else
		return NULL;
}


/*******************************************************************************

 $Function:    	ATB_wap_terminate

 $Description:	Closes the WAP application and frees all the memory allocated

 $Returns:		WAP_OK

 $Arguments:	parameter - see MMI_WAP_TERMINATE_IND

*******************************************************************************/

T_WAP_RES ATB_wap_terminate(T_MMI_WAP_TERMINATE_IND *parameter)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_terminate");
#endif

	/* SPR#1850 - SH - No longer terminate call here */

	M_MMI_WAP_TERMINATE_IND(parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_config_int

 $Description:	SPR#1921 - SH - Added
 				Sends integer configuration information to the browser

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View	- The current view
 				param	- ID of the configuration
 				value	- Integer value of the configuration

*******************************************************************************/

T_WAP_RES ATB_wap_config_int(T_WAP_VIEW *View, USHORT param, U32 value)
{
	T_MMI_WAP_CONFIGURE_IND parameter;
	parameter.object_id = View->object_id;
	parameter.type = WAP_IntConfig;
	parameter.param = param;
	parameter.intvalue = value;
	parameter.strvalue = NULL;
	parameter.length = 0;

	M_MMI_WAP_CONFIGURE_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_config_str

 $Description:	SPR#1921 - SH - Added
 				Sends string configuration information to the browser

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View	- The current view
 				param	- ID of the configuration
 				value	- Integer value of the configuration
 				string	- String value of the configuration
 				length	- Length of the string value

*******************************************************************************/

T_WAP_RES ATB_wap_config_str(T_WAP_VIEW *View, USHORT param, char *string, U32 length)
{
	T_MMI_WAP_CONFIGURE_IND parameter;
	parameter.object_id = View->object_id;
	parameter.type = WAP_StrConfig;
	parameter.param = param;
	parameter.intvalue = 0;
	parameter.strvalue = string;
	parameter.length = length;

	M_MMI_WAP_CONFIGURE_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_conn_config_int

 $Description:	SPR#1921 - SH - Added
 				Sends integer configuration information to the browser

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View	- The current view
 				param	- ID of the configuration
 				value	- Integer value of the configuration

*******************************************************************************/

T_WAP_RES ATB_wap_conn_config_int(T_WAP_VIEW *View, USHORT param, U32 value)
{
	T_MMI_WAP_CONNECTION_CONFIGURE_IND parameter;
	parameter.object_id = View->object_id;
	parameter.type = WAP_IntConfig;
	parameter.channel_id = View->channel;
	parameter.param = param;
	parameter.intvalue = value;
	parameter.strvalue = NULL;
	parameter.length = 0;

	M_MMI_WAP_CONNECTION_CONFIGURE_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_conn_config_str

 $Description:	SPR#1921 - SH - Added
 				Sends string configuration information to the browser

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View	- The current view
 				param	- ID of the configuration
 				value	- Integer value of the configuration
 				string	- String value of the configuration
 				length	- Length of the string value

*******************************************************************************/

T_WAP_RES ATB_wap_conn_config_str(T_WAP_VIEW *View, USHORT param, char *string, U32 length)
{
	T_MMI_WAP_CONNECTION_CONFIGURE_IND parameter;
	parameter.object_id = View->object_id;
	parameter.type = WAP_StrConfig;
	parameter.channel_id = View->channel;
	parameter.param = param;
	parameter.intvalue = 0;
	parameter.strvalue = string;
	parameter.length = length;

	M_MMI_WAP_CONNECTION_CONFIGURE_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_download_url

 $Description:	Requests the WAP browser to download a particular URL

 $Returns:		WAP_OK

 $Arguments:	View - The current view
 				URL	 - The URL to download
 				reload - TRUE if page is to be fetched from network, not cache.

*******************************************************************************/

T_WAP_RES ATB_wap_download_url(T_WAP_VIEW *View, char *URL, BOOL reload)
{
	T_MMI_WAP_DOWNLOAD_URL_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_download_url");
#endif

	parameter.object_id = View->object_id;
	parameter.Url = URL;
	parameter.url_length = (U32)(strlen(URL)+1);
	parameter.reload = reload;
	// Jun-08-2005 MMI-SPR-30291: Added patches from FG
	#ifdef FF_GPF_TCPIP
	parameter.view_height = View->cardHeight;
	parameter.view_width = View->cardWidth;
	#endif
	M_MMI_WAP_DOWNLOAD_URL_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_stop_download

 $Description:	Requests the WAP browser to stop downloading a particular URL

 $Returns:		WAP_OK

 $Arguments:	View - the current view

*******************************************************************************/

T_WAP_RES ATB_wap_stop_download(T_WAP_VIEW *View)
{
	T_MMI_WAP_BROWSE_CONTROL_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_stop_download");
#endif

	parameter.object_id = View->object_id;
	parameter.browse_command = WAP_DOWNLOAD_STOP;
	M_MMI_WAP_BROWSE_CONTROL_IND(&parameter);

	ATB_wap_status_change(View,ATB_WAP_NO_STATUS);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_card_refresh

 $Description:	Requests the WAP browser to refresh the current card from the network

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View - the current view

*******************************************************************************/

T_WAP_RES ATB_wap_card_refresh(T_WAP_VIEW *View)
{
	T_MMI_WAP_BROWSE_CONTROL_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_card_refresh");
#endif

	parameter.object_id = View->object_id;
	parameter.browse_command = WAP_CARD_REFRESH;
	M_MMI_WAP_BROWSE_CONTROL_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_card_display

 $Description:	Requests the WAP browser to redisplay a card held in the cache

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View - the current view

*******************************************************************************/

T_WAP_RES ATB_wap_card_display(T_WAP_VIEW *View)
{
	T_MMI_WAP_BROWSE_CONTROL_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_card_display");
#endif

	parameter.object_id = View->object_id;
	parameter.browse_command = WAP_CARD_DISPLAY;
	M_MMI_WAP_BROWSE_CONTROL_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_card_go_back

 $Description:	Requests the WAP browser to go to the previous card

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View - the current view

*******************************************************************************/

T_WAP_RES ATB_wap_card_go_back(T_WAP_VIEW *View)
{
	T_MMI_WAP_BROWSE_CONTROL_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_card_go_back");
#endif

	parameter.object_id = View->object_id;
	parameter.browse_command = WAP_CARD_GO_BACK;
	M_MMI_WAP_BROWSE_CONTROL_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_card_key_event

 $Description:	Requests the WAP browser react to a key event, up/down etc.

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View - the current view
 				keyType - the type of key selected

*******************************************************************************/

T_WAP_RES ATB_wap_card_key_event(T_WAP_VIEW *View, WAP_CONTROL_TYPES keyType)
{
	T_MMI_WAP_BROWSE_CONTROL_IND	command;
	T_MMI_WAP_DRAW_CARD_REQ			current_card;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_card_key_event");
#endif

#ifdef FF_GPF_TCPIP
	// xreddymn Jun-28-2005 MMI-SPR-32467	
	ATB_animated_GIF_clear();
#endif

	command.object_id = View->object_id;
	command.browse_command = keyType;
	M_MMI_WAP_BROWSE_CONTROL_IND(&command);

	/* For select, need to redraw card in order to update changed elements */

	if (keyType == WAP_KEY_SELECT)
	{
		current_card.object_id = View->object_id;
		M_MMI_WAP_DRAW_CARD_REQ(&current_card);
	}

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_key_selected

 $Description:	Send the id of the selected WAP key to the AUS browser.

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View - the current view
 				keyId - Key identifier

*******************************************************************************/

T_WAP_RES ATB_wap_key_selected(T_WAP_VIEW *View, USHORT keyId)
{

	T_MMI_WAP_KEY_SELECTED_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_key_selected");
#endif

	parameter.object_id = View->object_id;
	parameter.keyId = keyId;
	M_MMI_WAP_KEY_SELECTED_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_card scroll

 $Description:	Scroll to a y position on the current card

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View - the current view
 				scrollPos - Y position on card to which to scroll

*******************************************************************************/

T_WAP_RES ATB_wap_card_scroll(T_WAP_VIEW *View, SHORT scrollPos)
{
	T_MMI_WAP_BROWSE_CONTROL_IND	parameter;

	/* Make sure the scroll destination is on the card */

	if (scrollPos > (View->cardHeight-WAP_SCREEN_HEIGHT))
		scrollPos = View->cardHeight-WAP_SCREEN_HEIGHT;

	if (scrollPos<0)
		scrollPos = 0;

	/* Send the event */

	parameter.object_id = View->object_id;
	parameter.browse_command = WAP_KEY_SCROLL;
	parameter.browse_parameter = (USHORT)scrollPos;

	M_MMI_WAP_BROWSE_CONTROL_IND(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_input_dialog_closed

 $Description:	Provides the answer of an input dialog.

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	parameter	- Dialog confirmation information

*******************************************************************************/

T_WAP_RES ATB_wap_input_dialog_closed(T_MMI_WAP_INPUT_DIALOG_CNF *parameter)
{
	T_MMI_WAP_DRAW_CARD_REQ current_card;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_input_dialog_closed");
#endif

	M_MMI_WAP_INPUT_DIALOG_CNF(parameter);
	current_card.object_id = parameter->object_id;
	M_MMI_WAP_DRAW_CARD_REQ(&current_card);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_password_dialog_closed

 $Description:	Provides the answer of a password dialog.

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	parameter - Dialog confirmation information

*******************************************************************************/

T_WAP_RES ATB_wap_password_dialog_closed(T_MMI_WAP_PASSWORD_DIALOG_CNF *parameter)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_password_dialog_closed");
#endif

	M_MMI_WAP_PASSWORD_DIALOG_CNF(parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_confirm_dialog_closed

 $Description:	Provides the answer of a confirmation dialog.

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	parameter		- Dialog confirmation information

*******************************************************************************/

T_WAP_RES ATB_wap_confirm_dialog_closed(T_MMI_WAP_CONFIRM_DIALOG_CNF *parameter)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_confirm_dialog_closed");
#endif

	M_MMI_WAP_CONFIRM_DIALOG_CNF(parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_info_dialog_closed

 $Description:	Provides the answer of an info dialog.

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	parameter	- Dialog confirmation information

*******************************************************************************/

T_WAP_RES ATB_wap_info_dialog_closed(T_MMI_WAP_INFO_DIALOG_CNF *parameter)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_info_dialog_closed");
#endif

	M_MMI_WAP_INFO_DIALOG_CNF(parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_options_menu_select

 $Description:	The AUI will notify to the WAP.ATB the id of the selected item

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View - the current view

*******************************************************************************/

T_WAP_RES ATB_wap_options_menu_select(T_WAP_VIEW *View)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_options_menu_select");
#endif

	ATB_wap_card_key_event(View, WAP_KEY_SELECT);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_add_element

 $Description:	Add a new element to the element chain

 $Returns:		Pointer to the element

 $Arguments:	SPR#1721 - SH - Modified parameters slightly
 				View - 	the current view
 				type - the type of element (text, fieldset, image)

*******************************************************************************/

T_WAP_ELEMENT * ATB_wap_buffer_add_element(T_WAP_VIEW *View, WAP_ELEMENT_TYPE type)
{
	T_WAP_ELEMENT	*Element;
	T_WAP_ELEMENT	*ElementIndex;
	static USHORT	elementCount = 0;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_add_element");
#endif

	if (!View)
		return;

	/* Create the element */

	Element = (T_WAP_ELEMENT *)AUI_wap_memory_alloc(sizeof(T_WAP_ELEMENT));

	/* If it's the first element in the chain, it forms the element chain header */

	if (View->NewElementHeader == NULL)
	{
		View->NewElementHeader = Element;
		elementCount = 0;
	}

	/* Otherwise, find its place in the chain and add it */

	else
	{
		ElementIndex = View->NewElementHeader;
		while(ElementIndex->NextElement !=NULL)
			ElementIndex = ElementIndex->NextElement;
		ElementIndex->NextElement = Element;
	}

	Element->type		= type;
	Element->NextElement = NULL;

	elementCount++;

	return Element;
}

// xreddymn Jun-28-2005 MMI-SPR-32467
// Implementation for animated GIF image handling

#ifdef FF_GPF_TCPIP

// If value of WAP_MAX_ANIMATED_GIFS is changed, make sure
// that ATB_animated_GIF_image_CB_list is also updated and
// callbacks are added or removed as required.

#define WAP_MAX_ANIMATED_GIFS	8

// Structure that stores details about an animated GIF image
typedef struct
{
	T_WAP_MMI_SEND_IMAGE_IND	*image_ind;			// Pointer to image indication received from WAP adapter
	T_MFW_HND					timer_handle;		// Handle to timer created to animate the GIF image
	UBYTE						disposal;			// Disposal method for the current frame
	UBYTE						frame;				// Currently displayed frame number (1 to n_frames)
	UBYTE						n_frames;			// Total number of frames in the animation
	S16							x;
	S16							y;
	S16							width;
	S16							height;
	void 						*pGIFInfo;

} WAP_animated_GIF_image;

WAP_animated_GIF_image		WAP_animated_GIF_images[WAP_MAX_ANIMATED_GIFS];
S16 						n_WAP_animated_GIF_elements = 0;

#include "mfw_tim.h"
#include "mfw_win.h"

extern UBYTE wapmic_GIF_convert(void *pInfo, int frame, T_WAP_MMI_SEND_IMAGE_IND *input, T_WAP_MMI_SEND_IMAGE_IND *output, int *n_frames, UBYTE *delay, UBYTE *disposal);
extern void wapmic_GIF_close_decoder(void *data);
extern void *wapmic_GIF_open_decoder(void *data, int size);

extern T_MFW_HND AUI_wap_get_win(void);
extern void ATB_animated_GIF_image_CB (int index, T_MFW_EVENT event, MfwTim *tc);
extern U32 mfwCheckMemoryLeft(void);
extern U32 wapmicCheckMemoryLeft(void);
extern void AUI_wap_restore_background(S32 x1, S32 y1, S32 x2, S32 y2);

void WAP_FFS_log_message(char *s, int len);

/*******************************************************************************

 $Function:    	ATB_animated_GIF_image_X_CB

 $Description:	Callback functions to handle animated image timer expiries.

 $Returns:		None.

 $Arguments:	event = MFW event structure
 				tc = pointer to MFW timer element

*******************************************************************************/

void ATB_animated_GIF_image_0_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(0, event, tc);
}

void ATB_animated_GIF_image_1_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(1, event, tc);
}

void ATB_animated_GIF_image_2_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(2, event, tc);
}

void ATB_animated_GIF_image_3_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(3, event, tc);
}

void ATB_animated_GIF_image_4_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(4, event, tc);
}

void ATB_animated_GIF_image_5_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(5, event, tc);
}

void ATB_animated_GIF_image_6_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(6, event, tc);
}

void ATB_animated_GIF_image_7_CB (T_MFW_EVENT event, MfwTim *tc)
{
	ATB_animated_GIF_image_CB(7, event, tc);
}

// Array of callback functions
void (*ATB_animated_GIF_image_CB_list[WAP_MAX_ANIMATED_GIFS]) (T_MFW_EVENT event, MfwTim *tc) =
{
	ATB_animated_GIF_image_0_CB,
	ATB_animated_GIF_image_1_CB,
	ATB_animated_GIF_image_2_CB,
	ATB_animated_GIF_image_3_CB,
	ATB_animated_GIF_image_4_CB,
	ATB_animated_GIF_image_5_CB,
	ATB_animated_GIF_image_6_CB,
	ATB_animated_GIF_image_7_CB,
};

/*******************************************************************************

 $Function:    	ATB_animated_GIF_image_CB

 $Description:  Common callback function to handle animated image timer expiries.

 $Returns:      None.

 $Arguments:    index = When there is more than one animated GIF image being
                displayed, index is used to identify each image.
                event = MFW event structure
                tc = pointer to MFW timer element

*******************************************************************************/

void ATB_animated_GIF_image_CB (int index, T_MFW_EVENT event, MfwTim *tc)
{
	T_WAP_MMI_SEND_IMAGE_IND 	converted_image;
	UBYTE						delay;
	UBYTE						disposal;

	if(WAP_animated_GIF_images[index].frame == WAP_animated_GIF_images[index].n_frames)
	{
		WAP_animated_GIF_images[index].frame = 1;
	}
	else
	{
		WAP_animated_GIF_images[index].frame++;
	}
//	TRACE_EVENT_P1("\nATB_animated_GIF_image_CB, disposal = %d", WAP_animated_GIF_images[index].disposal);
	if((WAP_animated_GIF_images[index].disposal == 2) || (WAP_animated_GIF_images[index].disposal == 3))
	{
		AUI_wap_restore_background(WAP_animated_GIF_images[index].x,
			WAP_animated_GIF_images[index].y,
			WAP_animated_GIF_images[index].x + WAP_animated_GIF_images[index].width,
			WAP_animated_GIF_images[index].y + WAP_animated_GIF_images[index].height);
	}
	if(wapmic_GIF_convert(WAP_animated_GIF_images[index].pGIFInfo, WAP_animated_GIF_images[index].frame, WAP_animated_GIF_images[index].image_ind, &converted_image, NULL, &delay, &disposal))
	{
		WAP_animated_GIF_images[index].x = converted_image.pX + WAP_LEFT_BORDER;
		WAP_animated_GIF_images[index].y = converted_image.pY + WAP_TOP_BORDER;
		WAP_animated_GIF_images[index].width = converted_image.pWidth;
		WAP_animated_GIF_images[index].height = converted_image.pHeight;
		converted_image.bmpFormat = BMP_FORMAT_16BIT_LCD_COLOUR;
		if (ATB_wap_profile_setting(WAP_STATUS_SCALEIMAGES))						// Image is to be scaled
		{
			ATB_wap_buffer_image_scale((T_WAP_MMI_SEND_IMAGE_IND *)&converted_image);
		}
		else
		{
			ATB_wap_buffer_image_display((T_WAP_MMI_SEND_IMAGE_IND *)&converted_image);
		}
		micFree(converted_image.Image);
		WAP_animated_GIF_images[index].disposal = disposal;
		timSetTime(WAP_animated_GIF_images[index].timer_handle, delay * 10);
		timStart(WAP_animated_GIF_images[index].timer_handle);
	}
	else
	{
		timStop(WAP_animated_GIF_images[n_WAP_animated_GIF_elements].timer_handle);
		timDelete(WAP_animated_GIF_images[n_WAP_animated_GIF_elements].timer_handle);
	}
}

/*******************************************************************************

 $Function:    	ATB_animated_GIF_clear

 $Description:  Stops all animating images, image data is not released by this
                function. Image data is released when LEa_freeObject is called
                by the browser.

 $Returns:      None.

 $Arguments:    None.

*******************************************************************************/

void ATB_animated_GIF_clear(void)
{
	S16 i;
	for(i = 0; i < n_WAP_animated_GIF_elements; i++)
	{
		timStop(WAP_animated_GIF_images[i].timer_handle);
		timDelete(WAP_animated_GIF_images[i].timer_handle);
		wapmic_GIF_close_decoder(WAP_animated_GIF_images[i].pGIFInfo);
	}
	n_WAP_animated_GIF_elements = 0;
}

/*******************************************************************************

 $Function:    	ATB_animate_GIF_image

 $Description:  Called after displaying the first frame of a GIF image, this
                function will start a timer to animate the image. It also adds
                the image details to the WAP_animated_GIF_images array.

 $Returns:      None.

 $Arguments:    image_ind = Image indication containing details of the input
                            GIF image
                delay = duration after which the first frame must be removed
                disposal = disposal method to use for the first frame
                n_frames = Total number of frames (this is obtained when
                           the first frame is decoded)

*******************************************************************************/

void ATB_animate_GIF_image(void *pGIFInfo, S16 x, S16 y, S16 width, S16 height, T_WAP_MMI_SEND_IMAGE_IND *image_ind, UBYTE delay, UBYTE disposal, UBYTE n_frames)
{
	T_MFW_HND wap_win;
	S16 i;

	for(i = 0; i < n_WAP_animated_GIF_elements; i++)
	{
		if(WAP_animated_GIF_images[i].image_ind == image_ind)
		{
			return;
		}
	}
	wap_win=AUI_wap_get_win();//mfwParent(mfwHeader());
	if(!wap_win) return;
	if(n_WAP_animated_GIF_elements < (WAP_MAX_ANIMATED_GIFS-1))
	{
		WAP_animated_GIF_images[n_WAP_animated_GIF_elements].timer_handle = timCreate(wap_win, delay * 10, (MfwCb)ATB_animated_GIF_image_CB_list[n_WAP_animated_GIF_elements]);
		if(WAP_animated_GIF_images[n_WAP_animated_GIF_elements].timer_handle)
		{
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].pGIFInfo = pGIFInfo;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].image_ind = image_ind;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].disposal = disposal;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].frame = 1;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].n_frames = n_frames;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].x=x+WAP_LEFT_BORDER;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].y=y+WAP_TOP_BORDER;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].width=width;
			WAP_animated_GIF_images[n_WAP_animated_GIF_elements].height=height;
			timStart(WAP_animated_GIF_images[n_WAP_animated_GIF_elements].timer_handle);
			n_WAP_animated_GIF_elements++;
		}
	}
}

#endif // FF_GPF_TCPIP

/*******************************************************************************

 $Function:    	ATB_wap_buffer_display

 $Description:	Displays the card from the buffer

 $Returns:		None.

 $Arguments:	View - the current view

*******************************************************************************/

void ATB_wap_buffer_display(T_WAP_VIEW *View)
{
	T_WAP_ELEMENT				*Element		= View->ElementHeader;
	USHORT						elementCount	= 0;		/* No. of element */
	SHORT						titleX;						/* Position of title to centre it */
	SHORT						titleWidth;					/* Width of the title in pixels */
	double						doubleTemp;					/* Temporary double value */
	SHORT						scrollBarSize;				/* Size of scroll bar in pixels */
	SHORT						scrollBarPos;				/* Y position of top of scroll bar */
	SHORT						lineX;						/* First X position of line */
	SHORT						lineY;						/* First Y position of line */
	USHORT						*temp;						/* Temporary storage for text strings */
	UBYTE						scrollIndex;				/* For drawing scrollbar */
	USHORT						titleLen;					/* Length of title */

#ifdef FF_GPF_TCPIP
	// xreddymn Jun-28-2005 MMI-SPR-32467
	T_WAP_MMI_SEND_IMAGE_IND 	*image_ind;
	T_WAP_MMI_SEND_IMAGE_IND 	converted_image;
	UBYTE						delay;
	UBYTE						disposal;
	int							n_frames;
	SHORT						dx, dy;
#endif // FF_GPF_TCPIP

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_display");
#endif

#ifdef FF_GPF_TCPIP
	// xreddymn Jun-28-2005 MMI-SPR-32467
	ATB_animated_GIF_clear();
#endif // FF_GPF_TCPIP

	/* Display the title of the card, centred, over the line */

	temp = (USHORT *)AUI_wap_memory_alloc((CARD_TITLE_MAX_LEN+1)*sizeof(USHORT));
	/* SPR#1816 - SH - Obtain card title in MMI unicode */

	if (ATB_wap_status_get(View, ATB_WAP_DOWNLOADING))
	{
		/* Card is downloading */
		titleLen = AUI_wap_stringID(temp, CARD_TITLE_MAX_LEN, WAP_STRING_DOWNLOADING);
	}
	else if (ATB_wap_status_get(View, ATB_WAP_CARD_READING))
	{
		/* Card is updating */
		titleLen = AUI_wap_stringID(temp, CARD_TITLE_MAX_LEN, WAP_STRING_UPDATING);
	}
	else
	{
		/* Normal card title */
		titleLen = ATB_uc_text_copy(temp, View->Title, CARD_TITLE_MAX_LEN);
	}

	titleWidth = ATB_uc_text_width(temp, titleLen);		/* Width of the title */
	titleX = (WAP_TOTAL_WIDTH - titleWidth)/2;			/* Position of title to centre it */
	dspl_TextOut(titleX,0,DSPL_TXTATTR_SIGNED_COORDS | DSPL_TXTATTR_UNICODE, (char *)temp);

	AUI_wap_memory_free((UBYTE *)temp, (CARD_TITLE_MAX_LEN+1)*sizeof(USHORT));

	/* Horizontal scroll bar and top line */

	dspl_DrawLine(titleX-2, WAP_TOP_BORDER/2, 0, WAP_TOP_BORDER/2);	  /* Line to left of title */
	dspl_DrawLine(WAP_TOTAL_WIDTH-titleX+1, WAP_TOP_BORDER/2,
		WAP_TOTAL_WIDTH-WAP_VSCROLLBAR_WIDTH, WAP_TOP_BORDER/2);		/* Line to right of title */

	if (View->cardWidth>WAP_SCREEN_WIDTH)
	{
		doubleTemp = WAP_HSCROLLBAR_WIDTH*(double)WAP_SCREEN_WIDTH/(double)View->cardWidth;
		scrollBarSize = (SHORT)(doubleTemp+0.5);			/* Round to nearest int */
		if (scrollBarSize>WAP_HSCROLLBAR_WIDTH)
			scrollBarSize = WAP_HSCROLLBAR_WIDTH;

		doubleTemp = WAP_HSCROLLBAR_WIDTH*(double)View->cardXPosition/(double)View->cardWidth;
		scrollBarPos = (SHORT)(doubleTemp+0.5);				/* Round to nearest int */

		for (scrollIndex=0; scrollIndex<scrollBarSize; scrollIndex++)
		{
			dspl_DrawLine(scrollBarPos+scrollIndex, 0,
				scrollBarPos+scrollIndex, WAP_TOP_BORDER/2);
		}

		if (WAP_HSCROLLBAR_WIDTH<(titleX-1))
			dspl_DrawLine( WAP_HSCROLLBAR_WIDTH, 0, WAP_HSCROLLBAR_WIDTH, WAP_TOP_BORDER/2);
	}
#ifdef FF_GPF_TCPIP
        //xrashmic 21 Jan, 2005 MMI-SPR-28223
       pluginImageDisplayed=FALSE;
#endif
	/* Display the elements of the card one by one */
	while (Element!=NULL)
	{
		switch(Element->type)
		{
			case WAP_TEXT:
				/* Text Element */
				ATB_wap_buffer_text_draw((T_WAP_MMI_SEND_TEXT_IND *)Element->data);
				break;

			
//kyle 29 Jun, 2005 MMI-SPR-32462
			case WAP_BORDER:
				#ifdef FF_GPF_TCPIP
				ATB_wap_buffer_border_draw((T_WAP_MMI_DRAW_BORDER_IND *)Element->data);
				#endif
				break;

			
			case WAP_TABLE:
				/* Table/Fieldset element */
				ATB_wap_buffer_table_draw((T_WAP_MMI_SEND_TABLE_IND *)Element->data);
				break;
			case WAP_IMAGE:
				/* Image element */
#ifdef FF_GPF_TCPIP
                     case WAP_PLUGIN_IMAGE://xrashmic 21 Jan, 2005 MMI-SPR-28223
                       //xrashmic 21 Jan, 2005 MMI-SPR-28223
                       //When there is a plugin image, we disable scroll. Storing this info in pluginImageDisplayed
                            if(Element->type==WAP_IMAGE)
                                pluginImageDisplayed=FALSE;
                            else
                                pluginImageDisplayed=TRUE;
#endif
			// xreddymn Jun-28-2005 MMI-SPR-32467: Handling of GIF images
#ifdef FF_GPF_TCPIP
			image_ind = Element->data;
			if(!image_ind) break;
			if((image_ind->image_length > 2) && (strncmp((char*)image_ind->Image, "GIF", 3) == 0))
			{
				void *pGIFInfo;

				converted_image = *image_ind;
				pGIFInfo = wapmic_GIF_open_decoder(image_ind->Image, image_ind->image_length); 
				if(wapmic_GIF_convert(pGIFInfo, 1, image_ind, &converted_image, &n_frames, &delay, &disposal))
				{
					// TRACE_EVENT_P2("GIF image converted (%d, %d)",converted_image.pWidth, converted_image.pHeight);
					// TRACE_EVENT_P3("GIF frames=%d, delay=%d, disposal=%d",n_frames, delay, disposal);
//					TRACE_EVENT_P1("GIF URL = %s", wapmic_image_URL(image_ind->ImageReq));
					converted_image.bmpFormat = BMP_FORMAT_16BIT_LCD_COLOUR;
					if (ATB_wap_profile_setting(WAP_STATUS_SCALEIMAGES))						// Image is to be scaled
					{
						ATB_wap_buffer_image_scale((T_WAP_MMI_SEND_IMAGE_IND *)&converted_image);
					}
					else
					{
						ATB_wap_buffer_image_display((T_WAP_MMI_SEND_IMAGE_IND *)&converted_image);
					}
					micFree(converted_image.Image);
					if(n_frames > 1)
					{
						if((converted_image.pX >= 0) && 
						((converted_image.pX + converted_image.pWidth - 1) < (WAP_LEFT_BORDER + WAP_SCREEN_WIDTH - 1)) &&
						(converted_image.pY >= 0) &&
						((converted_image.pY + converted_image.pHeight - 1) < (WAP_TOP_BORDER + WAP_SCREEN_HEIGHT - 1)))
					{
							ATB_animate_GIF_image(pGIFInfo, converted_image.pX, converted_image.pY, converted_image.pWidth, converted_image.pHeight, 
								image_ind, delay, disposal, n_frames);
						}
						else if(image_ind->pluginImage)
						{
							ATB_animate_GIF_image(pGIFInfo, converted_image.pX, converted_image.pY, converted_image.pWidth, converted_image.pHeight, 
								image_ind, delay, disposal, n_frames);
						}
					}
                                  // Sep 06 2005  REF:  MMI-SPR-34048  x0012849
                                  //The ? symbol is appeared for pictures with single frame because decoder is not closed at all  and after
                                  // few instances of deocder are opened, trying to open further will result in memory error.
				      // To avoid this close the decoder each time its opened
					else  
					{
					   wapmic_GIF_close_decoder(pGIFInfo);
					}
				}
				else
				{
					USHORT elementX1, elementY1, elementX2, elementY2;
					elementX1 = (USHORT)image_ind->pX+WAP_LEFT_BORDER;
					elementY1 = (USHORT)image_ind->pY+WAP_TOP_BORDER;
					if(image_ind->pWidth < 14)
					{
						elementX2 = (USHORT)14 + elementX1 - 1;
					}
					else
					{
						elementX2 = (USHORT)image_ind->pWidth + elementX1 - 1;
					}
					if(image_ind->pHeight < 14)
					{
						elementY2 = (USHORT)14 + elementY1 - 1;
					}
					else
					{
						elementY2 = (USHORT)image_ind->pHeight + elementY1 - 1;
					}
					dspl_DrawRect(elementX1,elementY1, elementX2, elementY2);
					dspl_TextOut(elementX1 + 6, elementY1 + 0, DSPL_TXTATTR_SIGNED_COORDS, "?");
				}
			}
			else
#endif // FF_GPF_TCPIP
			{
#ifdef FF_GPF_TCPIP
				((T_WAP_MMI_SEND_IMAGE_IND *)Element->data)->transparency_flag = 0;
#endif
			#ifdef FF_GPF_TCPIP
				if (ATB_wap_profile_setting(WAP_STATUS_SCALEIMAGES))						// Image is to be scaled
			#else
				if (View->Status & WAP_STATUS_SCALEIMAGES)
			#endif
					ATB_wap_buffer_image_scale((T_WAP_MMI_SEND_IMAGE_IND *)Element->data);
				else
					ATB_wap_buffer_image_display((T_WAP_MMI_SEND_IMAGE_IND *)Element->data);
			}
			break;
		}
		elementCount++;
		Element = Element->NextElement;		/* Find the next element */
	}

	/* Vertical scroll bar and right frame */

	scrollBarSize = WAP_SCREEN_HEIGHT*WAP_SCREEN_HEIGHT/View->cardHeight;
	if (scrollBarSize>WAP_SCREEN_HEIGHT)
		scrollBarSize = WAP_SCREEN_HEIGHT;

	scrollBarPos = WAP_SCREEN_HEIGHT*View->cardYPosition/View->cardHeight;

	dspl_DrawLine(WAP_TOTAL_WIDTH-WAP_VSCROLLBAR_WIDTH, WAP_TOP_BORDER/2,
		WAP_TOTAL_WIDTH-WAP_VSCROLLBAR_WIDTH, WAP_SCREEN_BOTTOM);			/* Line to top of bar */

	for (scrollIndex=1; scrollIndex<WAP_VSCROLLBAR_WIDTH; scrollIndex++)
	{
		dspl_DrawLine(WAP_TOTAL_WIDTH-WAP_VSCROLLBAR_WIDTH+scrollIndex, scrollBarPos+WAP_TOP_BORDER,
			WAP_TOTAL_WIDTH-WAP_VSCROLLBAR_WIDTH+scrollIndex, scrollBarPos+WAP_TOP_BORDER+scrollBarSize);
	}

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_text_draw

 $Description:	Draws text

 $Returns:		None.

 $Arguments:	parameter	- the send text event

*******************************************************************************/

static void ATB_wap_buffer_text_draw(T_WAP_MMI_SEND_TEXT_IND *parameter)
{
	USHORT	*temp;			/* SPR#1816 - SH - Unicode string storage */
	SHORT	elementX;		/* X position of element on-screen */
	SHORT	elementY;		/* Y position of element on-screen */
	USHORT	textWidth;		/* Width of text to draw */
	USHORT textLength;		/* SPR#1816 - SH - Length of text */

	textWidth = parameter->pWidth;
	if ((textWidth + parameter->pX)>WAP_SCREEN_WIDTH)		/* if text goes off the screen, */
		textWidth = WAP_SCREEN_WIDTH-parameter->pX;			/* cut it down to size */

	elementX = (USHORT)parameter->pX+WAP_LEFT_BORDER;		/* Absolute position of text */
	elementY = (USHORT)parameter->pY+WAP_TOP_BORDER;		/* on screen */

	/* Draw special text features */

	switch(parameter->type)
	{
		case WAP_TEXT_OPTION:
                       // Apr 28 2005  REF:  MMI-SPR-30400 x0012849
                       // To see that box aligns with the text.
                       #ifdef FF_GPF_TCPIP
  			    elementY+=OFFSET_CHECKBOX; 
			  #endif		   
			/* An options menu item - draw checkbox */
			dspl_DrawRect(elementX,
				elementY+WAP_CHECKBOX_TOP, \
				elementX+WAP_CHECKBOX_WIDTH-1, \
				elementY+WAP_CHECKBOX_TOP+WAP_CHECKBOX_HEIGHT-1);

			/* Draw check if item is selected */

			if (parameter->selected)
			{
				dspl_DrawRect(elementX+WAP_CHECKBOX_INDENT, \
					elementY+WAP_CHECKBOX_TOP+WAP_CHECKBOX_INDENT, \
					elementX+WAP_CHECKBOX_WIDTH-1-WAP_CHECKBOX_INDENT, \
					elementY+WAP_CHECKBOX_TOP+WAP_CHECKBOX_HEIGHT-1-WAP_CHECKBOX_INDENT);
			}

			/* Shift text to right to make space for checkbox */

			elementX += (WAP_CHECKBOX_WIDTH+WAP_CHECKBOX_RIGHT);
			textWidth -= (WAP_CHECKBOX_WIDTH+WAP_CHECKBOX_RIGHT);
                     // Apr 28 2005  REF:  MMI-SPR-30400 x0012849
                     // To see that box aligns with the text.
                     #ifdef FF_GPF_TCPIP
          		  elementY-=OFFSET_CHECKBOX;
			#endif		 
			break;

		case WAP_TEXT_OPTIONGROUP:
			/* Option group titles are currently not distinguished from normal text */
			break;
	}

	/* SPR#1816 - SH - Allocate memory for unicode string */

	temp = (USHORT *)AUI_wap_memory_alloc((parameter->text_length+1)*sizeof(USHORT));

	/* SPR#1816 - SH - Copy text and convert to MMI unicode */

	ATB_uc_text_copy(temp, parameter->Text, (USHORT)parameter->text_length);
	ATB_uc_text_convert(temp, (USHORT)parameter->text_length);		/* SPR#1816 - SH - Swap bytes of unicode */

	/* SPR#1816 - SH - Crop text to fit width */
      // Apr 28 2005  REF:  MMI-SPR-30400 x0012849
      // For the text of the Drop down menu , no need to crop the text, instead call 
      // ATB_uc_text_cut, which will return the text that will fit to the screen, otherwise scroll bar will be 
      // overwritten with the text.
       if(WAP_TEXT_OPTION == parameter->type )
	     textLength = ATB_uc_text_cut(temp, parameter->text_length, textWidth);		   	
	else		
	     textLength = ATB_uc_text_crop(temp, parameter->text_length, textWidth);	

	if (!parameter->invert)
		dspl_TextOut((USHORT)elementX,(USHORT)elementY,DSPL_TXTATTR_SIGNED_COORDS | DSPL_TXTATTR_UNICODE,(char*)temp);
	else
		dspl_TextOut((USHORT)elementX,(USHORT)elementY,DSPL_TXTATTR_INVERS | DSPL_TXTATTR_SIGNED_COORDS | DSPL_TXTATTR_UNICODE, (char*)temp);

	AUI_wap_memory_free((UBYTE *)temp, (parameter->text_length+1)*sizeof(USHORT));

	return;
}

/*******************************************************************************

 $Function:    	ATB_wap_buffer_border_draw

 $Description:	Draws border
                //kyle 29 Jun, 2005 MMI-SPR-32462

 $Returns:		None.

 $Arguments:	

*******************************************************************************/
#ifdef FF_GPF_TCPIP
static void ATB_wap_buffer_border_draw(T_WAP_MMI_DRAW_BORDER_IND *parameter)
{

	LAYOUT_BORDER bottom, left, right, top;
		
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_border_draw");
#endif

	bottom = parameter->borderBottom;
	left = parameter->borderLeft;
	right = parameter->borderRight;
	top = parameter->borderTop;

	if (bottom.cssPropCode != CSS_VALUE_NONE)
	{
		bottom.pX += WAP_LEFT_BORDER;
		bottom.pY += WAP_TOP_BORDER;
		dspl_DrawFilledRect(bottom.pX, bottom.pY, bottom.pX + bottom.pWidth, bottom.pY + bottom.pHeight);		
	}

	if (left.cssPropCode != CSS_VALUE_NONE)
	{
		left.pX += WAP_LEFT_BORDER;
		left.pY += WAP_TOP_BORDER;
		dspl_DrawFilledRect(left.pX, left.pY, left.pX + left.pWidth, left.pY + left.pHeight);		
	}

	if (right.cssPropCode != CSS_VALUE_NONE)
	{
		right.pX += WAP_LEFT_BORDER;
		right.pY += WAP_TOP_BORDER;
		dspl_DrawFilledRect(right.pX, right.pY, right.pX + right.pWidth, right.pY + right.pHeight);		
	}

	if (top.cssPropCode != CSS_VALUE_NONE)
	{
		top.pX += WAP_LEFT_BORDER;
		top.pY += WAP_TOP_BORDER;
		dspl_DrawFilledRect(top.pX, top.pY, top.pX + top.pWidth, top.pY + top.pHeight);		
	}

	return;
}
#endif

/*******************************************************************************

 $Function:    	ATB_wap_buffer_table_draw

 $Description:	Draws a table, or a fieldset

 $Returns:		None.

 $Arguments:	parameter	- the send table event

*******************************************************************************/

static void ATB_wap_buffer_table_draw(T_WAP_MMI_SEND_TABLE_IND *parameter)
{
	SHORT	elementX	= parameter->pX+WAP_LEFT_BORDER;			/* Left edge position of table/fieldset */
	SHORT	elementY	= parameter->pY+WAP_TOP_BORDER;				/* Top edge position of table/fieldset */
	SHORT	top			= elementY+WAP_CHAR_HEIGHT/2;				/* Top of fieldset */
	SHORT	bottom		= elementY+parameter->pHeight-1; 			/* Bottom of table/fieldset */
	SHORT	right		= elementX+parameter->pWidth-1;				/* Right side of table/fieldset */
	SHORT	lineX;													/* X position of column line */
	SHORT	lineY;													/* Y position of row line */
	USHORT	*temp;													/* Temp storage for title. */
	USHORT	titleWidth;												/* Width of the title in pixels */
	USHORT titleLength;												/* Length of title */
	USHORT	index;													/* Index for columns and rows */

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_table_draw");
	TRACE_EVENT_P4( "Fieldset/table pX, pY, pWidth, pHeight: %d, %d, %d, %d",
		parameter->pX, parameter->pY, parameter->pWidth, parameter->pHeight);
#endif

	/* Convert title to MMI Unicode */

	temp = (USHORT *)AUI_wap_memory_alloc((parameter->title_length+1)*sizeof(USHORT));
	titleLength = parameter->title_length;
	ATB_uc_text_copy(temp, parameter->Title, titleLength);
	ATB_uc_text_convert(temp, titleLength);		/* Convert to MMI unicode */

	/* Crop title if it overshoots screen */

	if ((parameter->pX+gle_fieldset_spaceLeft+ATB_uc_text_width(temp, titleLength)) > WAP_SCREEN_WIDTH)
	{
		titleLength = ATB_uc_text_crop(temp, titleLength, WAP_SCREEN_WIDTH-parameter->pX-gle_fieldset_spaceLeft);
	}

	/* Crop title if it overshoots edge of fieldset */

	if ((gle_fieldset_spaceLeft+ATB_uc_text_width(temp, titleLength)+gle_fieldset_spaceRight) > parameter->pWidth)
	{
		titleLength = ATB_uc_text_crop(temp, titleLength, parameter->pWidth-gle_fieldset_spaceLeft-gle_fieldset_spaceRight);
	}

	titleWidth = ATB_uc_text_width(temp, titleLength);	/* Width of the title */

	/* Display title if it's onscreen */

	if (parameter->pY >= 0 && parameter->pY < WAP_TEXT_LOWEST)
	{
		dspl_TextOut(elementX+gle_fieldset_spaceLeft, elementY, DSPL_TXTATTR_SIGNED_COORDS | DSPL_TXTATTR_UNICODE, (char *)temp);
	}
	AUI_wap_memory_free((UBYTE *)temp, (parameter->title_length+1)*sizeof(USHORT));

	/* Horizontal lines */

	lineY = elementY+gle_cell_vBefore;
	ATB_wap_buffer_line_draw(elementX, bottom, right, bottom);	/* Bottom line of table */

	if (parameter->rows_length > 0)
		ATB_wap_buffer_line_draw(elementX, lineY, right, lineY);	/* Line under title */
	else
	{
		ATB_wap_buffer_line_draw(elementX+gle_fieldset_spaceLeft-2, top, elementX, top);     /* Line to left of title */
		ATB_wap_buffer_line_draw(elementX+gle_fieldset_spaceLeft+titleWidth+2, top, right, top);   /* right */
	}

	/* Row lines */

	if (parameter->rows_length > 1)
	{
		for (index=0; index<(parameter->rows_length-1); index++)
		{
			lineY += parameter->RowHeight[index]+gle_cell_spaceToBorder;
			ATB_wap_buffer_line_draw(elementX, lineY, right, lineY);
			lineY += gle_cell_borderExtent+gle_cell_spaceToBorder;
		}
	}

	/* Vertical lines */

	lineX = elementX+gle_cell_hBefore;

	if (parameter->rows_length == 0)
		lineY = top;												/* For fieldset */
	else
		lineY = elementY+gle_cell_vBefore;							/* For table */

	ATB_wap_buffer_line_draw(elementX, lineY, elementX, bottom);	/* Left hand line */

	/* Column lines */

	if (parameter->cols_length > 1)
	{
		for (index=0; index<(parameter->cols_length-1); index++)
		{
			lineX += parameter->ColWidth[index]+gle_cell_spaceToBorder;
			ATB_wap_buffer_line_draw(lineX, lineY, lineX, bottom);
			lineX += gle_cell_borderExtent+gle_cell_spaceToBorder;
		}
	}
	ATB_wap_buffer_line_draw(right, lineY, right, bottom);			/* Right hand line */

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_line_draw

 $Description:	Draws a line, making sure it fits on-screen

 $Returns:		None.

 $Arguments:	x1,y1 - Coordinates of the start of the line
 				x2,y2 - Coordinates of the end of the line

*******************************************************************************/

static void ATB_wap_buffer_line_draw(SHORT x1, SHORT y1, SHORT x2, SHORT y2)
{
	SHORT deltaX1;
	SHORT deltaY1;
	SHORT deltaX2;
	SHORT deltaY2;
	double m;

	ATB_wap_buffer_onscreen(x1,y1, &deltaX1, &deltaY1);
	ATB_wap_buffer_onscreen(x2,y2, &deltaX2, &deltaY2);

	if (x2==x1)
	{
		if (deltaX1)
			return;
		y1+=deltaY1;
		y2+=deltaY2;
	}
	else if (y2==y1)
	{
		if (deltaY1)
			return;
		x1+=deltaX1;
		x2+=deltaX2;
	}
	else
	{
		m = (y2-y1)/(x2-x1);
		if (deltaX1 || deltaY1)
		{
			x1 += deltaX1;
			y1 += m*deltaX1;
			if (!ATB_wap_buffer_onscreen(x1,y1,&deltaX1,&deltaY1))
				return;
		}
		if (deltaX2 || deltaY2)
		{
			x2 += deltaX2;
			y2 += m*deltaX2;
			if (!ATB_wap_buffer_onscreen(x2,y2,&deltaX2,&deltaY2))
				return;
		}
	}

	dspl_DrawLine(x1,y1,x2,y2);
	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_onscreen

 $Description:	Returns TRUE if the point supplied is on-screen

 $Returns:		TRUE if point is onscreen

 $Arguments:	x,y - coordinates of the point
 				deltaX, deltaY - returns offset from screen

*******************************************************************************/

static BOOL ATB_wap_buffer_onscreen(SHORT x, SHORT y, SHORT *deltaX, SHORT *deltaY)
{
	BOOL outcome = TRUE;
	*deltaX = 0;
	*deltaY = 0;

	if (x<WAP_LEFT_BORDER)
	{
		outcome = FALSE;
		*deltaX = WAP_LEFT_BORDER-x;
	}
	if (x>(WAP_SCREEN_RIGHT-1))
	{
		outcome = FALSE;
		*deltaX = (WAP_SCREEN_RIGHT-1)-x;
	}
	if (y<WAP_TOP_BORDER)
	{
		outcome = FALSE;
		*deltaY = WAP_TOP_BORDER-y;
	}
	if (y>(WAP_SCREEN_BOTTOM-1))
	{
		outcome = FALSE;
		*deltaY = (WAP_SCREEN_BOTTOM-1)-y;
	}

	return outcome;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_image_display

 $Description:	Trims an image to fit into the specified space, then displays it

 $Returns:		None.

 $Arguments:	image - the image to display

*******************************************************************************/

#ifdef FF_GPF_TCPIP
#define RGB16(r,g,b) (( ((b & 0xf8) >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8) ))
#define RGB32(r,g,b) (( (r << 16) & 0x00FF0000) | ((g << 8) & 0x0000FF00) | ( b & 0x000000FF))
#endif

static void ATB_wap_buffer_image_display(T_WAP_MMI_SEND_IMAGE_IND *image)
{
	UBYTE *Region;								/* Pointer to trimmed image */
	SHORT offsetX = 0;							/* Offsets from origin of original image... */
	SHORT offsetY = 0;							/* ...where trimmed image starts */
	SHORT scrWidth = image->pWidth;				/* Width of trimmed image on screen */
	SHORT scrHeight = image->pHeight;			/* Height of trimmed image on screen */
	SHORT elementX;								/* Its x position on the screen */
	SHORT elementY;								/* Its y position on the screen */
	USHORT byteWidth;							/* Width of original in bytes */
	USHORT scrByteWidth;						/* Width of screen image in bytes */
	USHORT	offsetByteWidth;
	USHORT heightIndex;
	USHORT widthIndex;
	USHORT memIndex = 0;
	UBYTE *Image = image->Image;				/* The image data */
	UBYTE pixShift;								/* Pixel shift, shift bytes by this amount */

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_image_display");
#endif

	byteWidth = image->pWidth/8;
	if (image->pWidth % 8)
		byteWidth++;

	elementX = image->pX;
	elementY = image->pY;

	/* If image starts off the left of the screen */

	if (elementX < 0)
	{
		offsetX = -elementX;					/* Set the X offset so it is trimmed appropriately */
		scrWidth -= offsetX;					/* Change its width */
		elementX = 0;							/* And place it at the left of the screen */
	}

	/* If image starts above the top of the screen */

	if (image->pY < 0)
	{
		offsetY = -elementY;					/* Set the Y offset so it is trimmed appropriately */
		scrHeight -= offsetY;					/* Change its height */
		elementY = 0;							/* And place it at the top of the screen */
	}

	/* If the image goes off the right of the screen, reduce its width */

	if ((elementX+scrWidth)>WAP_SCREEN_WIDTH)
		scrWidth = WAP_SCREEN_WIDTH-elementX;

	/* If the image goes off the bottom of the screen, trim its height */

	if ((elementY+scrHeight)>WAP_SCREEN_HEIGHT)
		scrHeight = WAP_SCREEN_HEIGHT-elementY;

	scrByteWidth = scrWidth/8;	/* Work out the width of the trimmed image in bytes */
	if (scrWidth % 8)
		scrByteWidth++;

#ifdef FF_GPF_TCPIP

  if (image->bmpFormat == BMP_FORMAT_16BIT_LCD_COLOUR) {
	long ColorVal;
	UINT32 clr;
	unsigned char* p;
    int x, y;
#if 0
    for (x = 0; x < image->pWidth; x++) {
      for (y = 0; y < image->pHeight; y++) {
        p = (unsigned char*)(image->Image + ((y * image->pWidth + x) * 2));
		ColorVal = 256*(p[0]) + (p[1]);
		clr = RGB32( (((0xf800 & ColorVal)>>11) << 3), (((0x07e0 & ColorVal)>>5) << 2), ((0x1f & ColorVal) << 3) );
        scrPoint(image->pX + WAP_LEFT_BORDER + x, image->pY + WAP_TOP_BORDER + y, clr);
      }
    }
#else
	if((scrWidth > 0) && (scrHeight > 0))
	{
		int offset = (offsetY * image->pWidth + offsetX) << 1;
		int old_offset;
		UINT16 col16;
		UBYTE *data = image->Image;
		int imageX = image->pX;
		int imageY = image->pY;
		if(imageX < 0) imageX = 0;
		if(imageY < 0) imageY = 0;
		imageX += WAP_LEFT_BORDER;
		imageY += WAP_TOP_BORDER;
		if(image->transparency_flag)
		{
			for(y = 0; y < scrHeight; y++)
			{
				old_offset = offset;
				for(x = 0; x < scrWidth; x++)
				{
					col16 = data[offset++] << 8;
					col16 |= data[offset++];
					if(col16 != 0xAAAA)
					{
						clr = RGB32( (((0xf800 & col16)>>11) << 3), (((0x07e0 & col16)>>5) << 2), ((0x1f & col16) << 3) );
			        	scrPoint(imageX + x, imageY + y, clr);
			        }
				}
				offset = old_offset + (image->pWidth << 1);
			}
		}
		else
		{
			for(y = 0; y < scrHeight; y++)
			{
				old_offset = offset;
				for(x = 0; x < scrWidth; x++)
				{
					col16 = data[offset++] << 8;
					col16 |= data[offset++];
					clr = RGB32( (((0xf800 & col16)>>11) << 3), (((0x07e0 & col16)>>5) << 2), ((0x1f & col16) << 3) );
		        	scrPoint(imageX + x, imageY + y, clr);
				}
				offset = old_offset + (image->pWidth << 1);
			}
		}
	}
#endif
    // dspl_BitBlt2(image->pX + WAP_LEFT_BORDER, image->pY + WAP_TOP_BORDER, image->pWidth, image->pHeight, (void *)image->Image, 0, image->bmpFormat);
    return;
  }
  #endif
	/* Allocate memory for the trimmed image */

	Region = (UBYTE *)AUI_wap_memory_alloc(scrByteWidth*scrHeight);

	offsetByteWidth = offsetX/8;
	pixShift = offsetX % 8;			/* Offset within the byte of the first pixel */

	Image += (offsetY*byteWidth)+offsetByteWidth;	/* Point to the first byte of the region to be isolated */

	/* Copy the trimmed region of the image into our allocated memory,
	 * inverting it as necessary */

	for (heightIndex = 0; heightIndex<scrHeight; heightIndex++)
	{
		for (widthIndex = 0; widthIndex<scrByteWidth; widthIndex++)
		{
			Region[memIndex] = Image[widthIndex] << pixShift;
			if ((offsetByteWidth+scrByteWidth)<byteWidth || widthIndex<(scrByteWidth-1))
				Region[memIndex] |= Image[widthIndex+1] >> (8-pixShift);

			if (!image->invert)
				Region[memIndex] ^= 0xFF;	/* De-invert it if not selected */

			memIndex++;
		}
		Image += byteWidth;					/* Move down one line */
	}

#ifdef TRACE_ATBWAPAUI
	TRACE_EVENT_P2( "byteWidth: %d, scrByteWidth: %d", byteWidth, scrByteWidth);
	TRACE_EVENT_P4( "pX: %d, pY: %d, pWidth: %d, pHeight: %d", image->pX, image->pY, image->pWidth, image->pHeight);
	TRACE_EVENT_P4( "offsetX: %d, offsetY: %d, scrWidth: %d, scrHeight: %d", offsetX, offsetY, scrWidth, scrHeight);
	TRACE_EVENT_P2( "elementX: %d, elementY: %d", elementX, elementY);
	TRACE_EVENT_P2( "Region size: %d, should be: %d", memIndex, scrByteWidth*scrHeight);
#endif

	/* Display the image */

	dspl_BitBlt (elementX+WAP_LEFT_BORDER, elementY+WAP_TOP_BORDER, scrWidth, scrHeight, 0, (void *)Region, 0);

	/* Free the memory */

	AUI_wap_memory_free(Region, scrByteWidth*scrHeight);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_image_scale

 $Description:	Scales an image to fit into a specified space

 $Returns:		None.

 $Arguments:	View - pointer to the appropriate view

*******************************************************************************/

static void ATB_wap_buffer_image_scale(T_WAP_MMI_SEND_IMAGE_IND *image)
{
	T_WAP_MMI_SEND_IMAGE_IND *Scaled = NULL;
	SHORT	newWidth;
	SHORT	newHeight;
	USHORT heightIndex;
	USHORT widthIndex;
	USHORT oldIndex;
	USHORT	newIndex;
	USHORT	byteWidth;
	USHORT	scrByteWidth;
	UBYTE	*Image = image->Image;
	UBYTE	oldMask;						/* Pixel shift, shift bytes by this amount */
	UBYTE	newMask;
	UBYTE	pixel;
	USHORT	xScale;
	USHORT	xScaleOld;
	USHORT	yScale;
	USHORT	yScaleOld;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_image_scale");
#endif

#ifdef FF_GPF_TCPIP
  if (image->bmpFormat == BMP_FORMAT_16BIT_LCD_COLOUR) {
    ATB_wap_buffer_image_display(image);
    return;
  }
#endif
  Scaled = (T_WAP_MMI_SEND_IMAGE_IND *)AUI_wap_memory_alloc(sizeof(T_WAP_MMI_SEND_IMAGE_IND));																// Pointer to scaled image

	/* Squash to fit horizontally */

	if (image->pWidth > WAP_SCREEN_WIDTH)
		newWidth = WAP_SCREEN_WIDTH;
	else
		newWidth = image->pWidth;

	/* Squash to fit vertically */

	if (image->pHeight > WAP_SCREEN_HEIGHT)
		newHeight = WAP_SCREEN_HEIGHT;
	else
		newHeight = image->pHeight;

	/* Work out the width of the original image in bytes */

	byteWidth = image->pWidth/8;
	if (image->pWidth % 8)
		byteWidth++;

	/* Work out the width of the scaled image in bytes */
	scrByteWidth = newWidth/8;
	if (newWidth % 8)
		scrByteWidth++;

	/* Allocate memory for the scaled image */

	Scaled->Image = (UBYTE *)AUI_wap_memory_alloc(scrByteWidth*newHeight);

	oldIndex = -1;
	newIndex = -1;
	yScaleOld = 0;

	/* Scale the image */

	for (heightIndex = 0; heightIndex<image->pHeight; heightIndex++)
	{
		yScale = (USHORT) (heightIndex+1)*newHeight/image->pHeight;

		if (yScale != yScaleOld)
		{
			oldMask = 1;		/* Mask within the byte of the first pixel */
			newMask = 1;
			xScaleOld = 0;

			for (widthIndex = 0; widthIndex<image->pWidth; widthIndex++)
			{
				xScale = (USHORT) (widthIndex+1)*newWidth/image->pWidth;

				if (oldMask == 1)
				{
					oldMask = 128;
					oldIndex++;
				}
				else
					oldMask /= 2;

				if (xScale != xScaleOld)
				{
					if (newMask == 1)
					{
						newMask = 128;
						newIndex++;
						Scaled->Image[newIndex] = 0;
					}
					else
						newMask /= 2;

					if (Image[oldIndex] & oldMask)							/* If old pixel set, */
						Scaled->Image[newIndex] |= newMask;					/* set new pixel */
				}

				xScaleOld = xScale;
			}
		}
		else
		{
			oldIndex += byteWidth;
		}
		yScaleOld = yScale;
	}

#ifdef TRACE_ATBWAPAUI
	TRACE_EVENT_P2( "byteWidth: %d, scrByteWidth: %d", byteWidth, scrByteWidth);
	TRACE_EVENT_P4( "pX: %d, pY: %d, pWidth: %d, pHeight: %d",
		image->pX, image->pY, image->pWidth, image->pHeight);
	TRACE_EVENT_P2( "newWidth: %d, newHeight: %d", newWidth, newHeight);

#endif

	/* Display the image */

	Scaled->object_id = image->object_id;
	Scaled->image_length = scrByteWidth*newHeight;
	Scaled->invert = image->invert;
	Scaled->pX = image->pX;
	Scaled->pY = image->pY;
	Scaled->pWidth = newWidth;
	Scaled->pHeight = newHeight;
	Scaled->selected = image->selected;

	ATB_wap_buffer_image_display(Scaled);

	/* Free the memory */

	AUI_wap_memory_free(Scaled->Image, scrByteWidth*newHeight);
	AUI_wap_memory_free((UBYTE *)Scaled, sizeof(T_WAP_MMI_SEND_IMAGE_IND));

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_clear

 $Description:	Clears the element buffer

 $Returns:		None.

 $Arguments:	View - pointer to the appropriate view

*******************************************************************************/

void ATB_wap_buffer_clear(T_WAP_VIEW *View)
{
	T_WAP_ELEMENT					*Element	= View->ElementHeader;
	T_WAP_ELEMENT					*NextElement;
	T_WAP_MMI_SEND_TEXT_IND			*TextElement;
	T_WAP_MMI_SEND_TABLE_IND 		*TableElement;
	T_WAP_MMI_SEND_IMAGE_IND 		*ImageElement;
	USHORT 							elementCount = 0;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_clear");
#endif

#ifdef FF_GPF_TCPIP
	// xreddymn Jun-28-2005 MMI-SPR-32467
	ATB_animated_GIF_clear();
#endif // FF_GPF_TCPIP

	while (Element != NULL)
	{
		switch (Element->type)
		{
			case WAP_TEXT:
				/* Delete a text element */
				TextElement = (T_WAP_MMI_SEND_TEXT_IND *)Element->data;
				if (TextElement->text_length != 0)
					AUI_wap_memory_free((UBYTE *)TextElement->Text, TextElement->text_length*sizeof(USHORT));
				if (TextElement->formatstring_length != 0)
				{
					AUI_wap_memory_free((UBYTE *)TextElement->Formatstring,
						TextElement->formatstring_length*sizeof(USHORT));
				}
				AUI_wap_memory_free((UBYTE *)TextElement, sizeof(T_WAP_MMI_SEND_TEXT_IND));
				break;

			case WAP_TABLE:
				/* Delete a table/fieldset element */
				TableElement = (T_WAP_MMI_SEND_TABLE_IND *)Element->data;
				if (TableElement->title_length != 0)
					AUI_wap_memory_free((UBYTE *)TableElement->Title, TableElement->title_length*sizeof(USHORT));
				if (TableElement->cols_length != 0)
					AUI_wap_memory_free((UBYTE *)TableElement->ColWidth, TableElement->cols_length*sizeof(SHORT));
				if (TableElement->rows_length != 0)
					AUI_wap_memory_free((UBYTE *)TableElement->RowHeight, TableElement->rows_length*sizeof(SHORT));
				AUI_wap_memory_free((UBYTE *)TableElement, sizeof(T_WAP_MMI_SEND_TABLE_IND));
				break;

			case WAP_IMAGE:
				/* Delete an image element */
				ImageElement = (T_WAP_MMI_SEND_IMAGE_IND *)Element->data;
				if (ImageElement->image_length != 0)
					AUI_wap_memory_free((UBYTE *)ImageElement->Image, ImageElement->image_length*sizeof(UBYTE));
				AUI_wap_memory_free((UBYTE *)ImageElement, sizeof(T_WAP_MMI_SEND_IMAGE_IND));
				break;
		}

		NextElement = Element->NextElement;
		AUI_wap_memory_free((UBYTE *)Element, sizeof(T_WAP_ELEMENT));
		Element = NextElement;
		elementCount++;
	}

	/* Element chain is now empty */

	View->ElementHeader = NULL;

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_buffer_identify_element

 $Description:	Identifies which element is selected (based on the invert property) and
 				returns an appropriate type.

 $Returns:		The type of the element that is selected, or NULL if none

 $Arguments:	View	- pointer to the view

*******************************************************************************/

UBYTE ATB_wap_buffer_identify_element(T_WAP_VIEW *View)
{
	T_WAP_ELEMENT				*Element	= View->ElementHeader;
	T_WAP_MMI_SEND_TEXT_IND		*TextElement;
	T_WAP_MMI_SEND_IMAGE_IND	*ImageElement;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_buffer_identify_element");
#endif

	while (Element!=NULL)
	{
		switch (Element->type)
		{
			case WAP_TEXT:
				TextElement = (T_WAP_MMI_SEND_TEXT_IND *)Element->data;
				if (TextElement->invert)
				{
					return TextElement->type;
				}
				break;

			case WAP_IMAGE:
#ifdef FF_GPF_TCPIP
			case WAP_PLUGIN_IMAGE:
				//xrashmic 21 Jan, 2005 MMI-SPR-28223
				ImageElement = (T_WAP_MMI_SEND_IMAGE_IND *)Element->data;
                            //xrashmic 28 Jan, 2005 MMI-SPR-28166
                            //When the card contains the plugin Image, we need to send this
                            //indication, so that Save can be provided in the option menu
                                if(ImageElement->pluginImage)
                            {
                                  return WAP_PLUGINIMAGE;
                            }
				else if (ImageElement->invert)
				{
					return WAP_SELECTABLE_IMAGE;
				}
#else
				if (ImageElement->invert)
				{
					return WAP_SELECTABLE_IMAGE;
				}
#endif
				break;
		}
		Element = Element->NextElement;
	}

	/* Element not identified */

	return NULL;
}


/*******************************************************************************

 $Function:    	ATB_wap_profile_read

 $Description:	Reads in the specified profile and changes the ProfileId

 $Returns:		WAP_OK

 $Arguments:	View		- Pointer to the current view
 				ProfileId	- the id of the profile to read from the flash

*******************************************************************************/
#ifdef FF_GPF_TCPIP

T_WAP_RES ATB_wap_profile_read(T_WAP_VIEW *View, UBYTE ProfileId)
{
	T_WAP_VIEW		*ViewIndex;
	T_WAP_PROFILE	*Profile = &(WapProfilesData->Profile[ProfileId]);
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_read");
#endif

	if (View_header==NULL || Profile==NULL)
	{
		return WAP_FAIL;
	}

	WapData->ProfileId = ProfileId;

	/* SPR#2086 - SH - Change the profile for all open views */

	ViewIndex = View_header;
	while (ViewIndex!=NULL)
	{
		ViewIndex->ProfileId = ProfileId;
		ViewIndex->Profile = Profile;
		/* Go to next view */
		ViewIndex = ViewIndex->NextView;
	}

	return WAP_OK;
}

#else /* #ifdef FF_GPF_TCPIP */

T_WAP_RES ATB_wap_profile_read(T_WAP_VIEW *View, UBYTE ProfileId)
{
	T_WAP_PROFILE	*Profile		= View->Profile;
	UBYTE 			entryIndex;
	char			*Entry;
	char			*URL;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_read");
#endif

	View->ProfileId	= ProfileId;
	View->Profile	= &(WapProfilesData->Profile[View->ProfileId]);

#ifndef GPRS
	/* SPR#2324 - SH - Ensure that all profiles are of dialup type if GPRS is off */
	if (View->Profile->AccessType==WAP_GPRS_DATA)
	{
		View->Profile->AccessType = WAP_CS_DATA;
	}
#endif

	return WAP_OK;
}

#endif /* !#ifdef FF_GPF_TCPIP */
/*******************************************************************************

 $Function:    	ATB_wap_profile_names_read

 $Description:	Reads into RAM the names of all profiles stored in flash, also
 				the global bookmarks and history lists

 $Returns:		WAP_OK

 $Arguments:	Profile		- Pointer to the current profile

*******************************************************************************/

T_WAP_RES ATB_wap_profile_names_read(T_WAP_VIEW *View)
{
	T_WAP_PROFILE	*Profile;
	T_WAP_LIST 		*ProfilesList	= View->ProfilesList;
	USHORT			no_of_bookmarks;
	T_WAP_LIST		*Bookmarks		= View->Bookmarks;
	T_WAP_LIST		*BookmarksURL	= View->BookmarksURL;
	USHORT			no_of_history;
	T_WAP_LIST		*History		= View->History;
	T_WAP_LIST		*HistoryURL		= View->HistoryURL;
	UBYTE			entryIndex;
	char			*Entry;
	char			*URL;
	UBYTE			no_of_profiles;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_names_read");
#endif

	/* SPR#2086 - SH - FFS files now read when view created.
	 * Read in number of profiles. */
#ifdef CO_UDP_IP
	/* Default values are provided.  If either of the files 'mmi/wapdata'
	 * or 'mmi/wapprof' aren't found, files is created with these defaults.
	 * The '0' size indicator indicates that one of the files was not present. */

	if (flash_wap_read() == 0)
	{
		ATB_wap_profile_default_create(FALSE); /* SPR#2324 */
	}

	View->Status 		= WapData->Status;		/* Status flags for settings */
	View->ProfileId		= WapData->ProfileId;	/* Default starting profile */

	/* Read in profiles list */
#endif


	no_of_profiles = WapData->no_of_profiles;
	ProfilesList->no_of_entries = no_of_profiles;
	/* Get list of profile names */

	for (entryIndex = 0; entryIndex<MAX_PROFILES; entryIndex++)
	{
		ProfilesList->Entry[entryIndex] = (char *)WapProfilesData->Profile[entryIndex].Title;
	}

	/* Read in bookmarks */

	no_of_bookmarks = WapData->no_of_bookmarks;
	Bookmarks->no_of_entries	= no_of_bookmarks;
	BookmarksURL->no_of_entries	= no_of_bookmarks;

	/* SPR#1816 - SH - Cast to char */

	for (entryIndex = 0; entryIndex<MAX_BOOKMARKS; entryIndex++)
	{
		Bookmarks->Entry[entryIndex] = (char *)WapData->Bookmarks[entryIndex];
		BookmarksURL->Entry[entryIndex] = WapData->BookmarksURL[entryIndex];
	}

	/* Read in history entries */

	no_of_history = WapData->no_of_history;
	History->no_of_entries 	= no_of_history;
	HistoryURL->no_of_entries  = no_of_history;

	for (entryIndex = 0; entryIndex<MAX_HISTORY; entryIndex++)
	{
		History->Entry[entryIndex] = (char *)WapData->History[entryIndex];
		HistoryURL->Entry[entryIndex] = WapData->HistoryURL[entryIndex];
	}

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_profile_save

 $Description:	Store the current updated profile in flash

 $Returns:		WAP_OK

 $Arguments:	View		- Pointer to the current view

*******************************************************************************/

#ifdef FF_GPF_TCPIP
T_WAP_RES ATB_wap_profile_save(T_WAP_VIEW *View)
{

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_save");
#endif

	/* SPR#2086 - SH - Write bookmarks information only if this is
	 * a browser view */

	if (View->Bookmarks)
	{
		WapData->no_of_bookmarks = View->Bookmarks->no_of_entries;
	}
	if (View->History)
	{
		WapData->no_of_history = View->History->no_of_entries;
	}

    WapData->ProfileId = View->ProfileId;
     //xrashmic 16 Dec, 2004 MMI-SPR-27622
     // Save the total number of profiles to flash.
    WapData->no_of_profiles		= View->ProfilesList->no_of_entries;
	flash_wap_write();

	return WAP_OK;
}

/*******************************************************************************

 $Function:    	ATB_wap_profile_delete

 $Description:	Deletes a profile, and shifts other profiles up to fill the gap
 				 //xrashmic 16 Dec, 2004 MMI-SPR-27622
 
 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View		- Pointer to the current view
 				ProfileId	- ID of the profile to delete
 
*******************************************************************************/

T_WAP_RES ATB_wap_profile_delete(T_WAP_VIEW *View, UBYTE ProfileId)
{
	UBYTE profileIndex;
	
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_save");
#endif
	
	if (ProfileId >= View->ProfilesList->no_of_entries)
	{
		return WAP_FAIL;
	}

	View->ProfilesList->no_of_entries--;
	
	for (profileIndex = ProfileId; profileIndex < View->ProfilesList->no_of_entries; profileIndex++)
	{
		memcpy((void *)&WapProfilesData->Profile[profileIndex],
				(void *)&WapProfilesData->Profile[profileIndex+1],
				sizeof(T_WAP_PROFILE));
	}
	return WAP_OK;
}

#else /* #ifdef FF_GPF_TCPIP */

T_WAP_RES ATB_wap_profile_save(T_WAP_VIEW *View)
{

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_save");
#endif

	WapData->ProfileId			= View->ProfileId;
	WapData->Status				= View->Status;
	WapData->no_of_bookmarks	= View->Bookmarks->no_of_entries;
	WapData->no_of_history		= View->History->no_of_entries;
	WapData->no_of_profiles		= View->ProfilesList->no_of_entries; /*SPR#2324 - SH - Save no. of profiles */
	flash_wap_write();

	return WAP_OK;
}

/*******************************************************************************

 $Function:    	ATB_wap_profile_delete

 $Description:	Deletes a profile, and shifts other profiles up to fill the gap
 				SPR#2324 - SH - Added

 $Returns:		WAP_OK if successful, WAP_FAIL if otherwise

 $Arguments:	View		- Pointer to the current view
 				ProfileId	- ID of the profile to delete

*******************************************************************************/

T_WAP_RES ATB_wap_profile_delete(T_WAP_VIEW *View, UBYTE ProfileId)
{
	UBYTE profileIndex;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_save");
#endif

	if (ProfileId >= View->ProfilesList->no_of_entries)
	{
		return WAP_FAIL;
	}

	View->ProfilesList->no_of_entries--;

	for (profileIndex = ProfileId; profileIndex < View->ProfilesList->no_of_entries; profileIndex++)
	{
		memcpy((void *)&WapProfilesData->Profile[profileIndex],
				(void *)&WapProfilesData->Profile[profileIndex+1],
				sizeof(T_WAP_PROFILE));
	}

	return WAP_OK;
}


#endif /* !#ifdef FF_GPF_TCPIP */



/*******************************************************************************

 $Function:    	ATB_wap_profile_default_create

 $Description:	Creates a default profile in the flash if one isn't already there
 				SPR#1794 - SH - There's now a third default profile.
				SPR#1816 - SH - Convert all defaults to MMI unicode
 $Returns:

 $Arguments:

*******************************************************************************/
#ifdef FF_GPF_TCPIP
//TISHMMS Project
T_WAP_RES ATB_wap_profile_default_create()
{
	UBYTE	no_of_bookmarks		= 9;
	char	*bookmarksList[] =
	{
		"ZgFg wml",
		"ZgFg html",
		"Google",
		"Yahoo!",
		"Financial Times",
		"Cnet tech news",
		"T-Mobile UK",
		"WEB.DE",
		"El Pais"
	};

	char 	*bookURLList[]	=
	{
		"http://wap.fgmicrotec.hr",
		"http://www.fgmicrotec.hr/test/dsample.htm",
		"http://wap.google.com",
		"http://wap.yahoo.com",
		"http://wap.ft.com",
		"http://wap.cnet.com",
		"http://wap.t-mobile.co.uk",
		"http://wap.web.de",
		"http://wap.elpais.es"
	};

	UBYTE	no_of_history		= 0;
	char	*historyList[]		= { "dummy" };
	char	*histURLList[]		= { "www.dummy.org" };

	UBYTE	no_of_profiles	= 8;
	char 	*profilesDefault[] 	= { "fg.vip.gprs", "vip.gprs", "fg.ht.gprs", "ht.gprs", "D1.gprs", "D2.gprs", "E-Plus.gprs", "O2.gprs", "Empty"};
	char	*homepageURL[]		= { "http://wap.fgmicrotec.hr",	"http://wap.vip.hr",	"http://wap.fgmicrotec.hr",	"http://wap.fgmicrotec.hr",	"http://wap.yahoo.com",	"http://wap.yahoo.com",		"http://wap.yahoo.com",	"http://wap.yahoo.com",	"http://wap.yahoo.com"};
	char	*IPAddress1[]			= { "217.014.220.081",			"212.091.099.091",		"217.014.220.081",			"010.012.000.003",			"193.254.160.002",			"139.007.029.001",				"212.023.097.009",			"195.182.114.052",			"000.000.000.000"};
	char	*IPAddress2[]			= { "217.014.220.081",			"212.091.099.091",		"217.014.220.081",			"000.000.000.000",			"193.254.160.002",			"139.007.029.001",				"212.023.097.009",			"195.182.114.052",			"000.000.000.000"};
	char	*DialupNumber[]		= { "00448704290000",			"00448704290000",	"00448704290000",		"00448704290000",		"17266",					"00491722290100",			"00448456609561",		"00448456609561",		""};
	char	*APN[]				= { "gprs5.vipnet.hr",			"gprs5.vipnet.hr",		"www.htgprs.hr",			"www.htgprs.hr",			"wap.t-d1.de",			"wap.vodafone.de",				"wap.eplus.de",			"wap.viaginterkom.de",	""};
	char	*Username[]			= { "38591",					"38591",				"",							"",							"t-d1",					"",								"eplus",				"",						""};
	char	*Password[]			= { "38591",					"38591",				"",							"",							"wap",					"",								"wap",					"",						""};
	UBYTE AccessType[]			= { WAP_GPRS_DATA, WAP_GPRS_DATA,	WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_CS_DATA};
	UBYTE ConnectionSpeed[]	= { WAP_ISDN9600, 			WAP_ISDN9600, 		WAP_ISDN9600, 			WAP_ISDN9600, 			WAP_ISDN9600, 			WAP_ISDN9600, 				WAP_ISDN9600, 			WAP_ISDN9600,			WAP_ISDN9600};
	USHORT	ResponseTimer[]		= {60, 60, 60, 60, 60, 60, 60, 60, 60};
	USHORT	Port1[]				= {9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201};
	USHORT	Port2[]				= {9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201};
//xpradipg - Aug 4: Added the default values for the WAP2.0 Menu Items
//Need to confirm these default values

	char *NameServer1[]		= { "000.000.000.000",			"000.000.000.000",		"000.000.000.000",		"000.000.000.000",		"000.000.000.000",		"139.007.029.001",			"212.023.097.009",		"195.182.114.052",		"000.000.000.000"};
	char *NameServer2[]		= { "000.000.000.000",			"000.000.000.000",		"000.000.000.000",		"000.000.000.000",		"000.000.000.000",		"139.007.029.001",			"212.023.097.009",		"195.182.114.052",		"000.000.000.000"};
	BOOL PPGAuthentication[]	= {FALSE, FALSE, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE};
	BOOL WirelessProfiledHTTP[]={ TRUE,TRUE, TRUE, TRUE, TRUE,TRUE, TRUE, TRUE};

/*
// Germany MMS settings from Tristan (?)
	UBYTE	no_of_profiles	= 4;
	char 	*profilesDefault[] 	= { "T-Mobile", "Vodafone", "E-Plus","O2"};
	char	*IPAddress1[]		= { "193.254.160.003", "139.007.029.017", "212.023.097.153", "195.182.114.052"};
	char	*IPAddress2[]		= { "000.000.000.000", "139.007.029.017", "212.023.097.153", "195.182.114.052"};
	char	*DialupNumber[]		= { "17266", "00447836900808", "00448456609561","00448456609561" };
	char	*APN[]				= { "mms.t-d1.de", "event.vodafone.de", "mms.eplus.de", "wap.viaginterkom.de"};
	char	*Username[]			= { "t-mobil", "", "mms", "" };
	char	*Password[]			= { "mms", "", "eplus", "" };
	UBYTE AccessType[]			= { WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA };
	UBYTE ConnectionSpeed[]		= { WAP_ISDN9600, WAP_ISDN9600, WAP_ISDN9600, WAP_ISDN9600};
	USHORT	ResponseTimer[]		= {180,60,120, 120};
	USHORT	Port1[]				= {9201,9201,9201, 9201};
	USHORT	Port2[]				= {9201,9201,9201, 9201};
// MMS settings from Tristan (?)
	UBYTE	no_of_profiles	= 3;
	char 	*profilesDefault[] 	= { "CNMobile", "Orange", "Magic4"};
	char	*homepageURL[]		= { "http://wap.yahoo.com", "http://plus.orangehk.com", "http://plus.orangehk.com"};
	char	*IPAddress1[]		= { "010.000.000.172", "010.030.003.151", "010.030.003.151"};
	char	*IPAddress2[]		= { "010.000.000.172", "010.030.003.151", "010.030.003.151"};
	char	*DialupNumber[]		= { "17266", "00447836900808", "00448456609561" };
	char	*APN[]				= { "CMWAP", "web.orangehk.com", "web.orangehk.com"};
	char	*Username[]			= { "WAP", "", "" };
	char	*Password[]			= { "WAP", "", "" };
	UBYTE AccessType[]			= { WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA };	/* SPR#1189 - SH - Added
	UBYTE ConnectionSpeed[]		= { WAP_ISDN9600, WAP_ISDN14400, WAP_ISDN14400};/* SPR#1827 - SH - Default connection speed values
	USHORT	ResponseTimer[]		= {180,60,120};
	USHORT	Port1[]				= {9201,9201,9201};
	USHORT	Port2[]				= {9201,9201,9201};
*/

	USHORT entryIndex;
	USHORT	profile;
	char number[NUMBER_PADDING+1];	 /* SPR#1816 -SH */

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_default_create");
#endif

	WapData->ProfileId		= 0;
	WapData->Status = WAP_STATUS_SAVEHISTORY | WAP_STATUS_SCALEIMAGES;

	/* Copy bookmarks into WapData structure */

	WapData->no_of_bookmarks = no_of_bookmarks;

	for (entryIndex = 0; entryIndex<no_of_bookmarks; entryIndex++)
	{
		ATB_char_to_uc(WapData->Bookmarks[entryIndex], bookmarksList[entryIndex]);
		strcpy(WapData->BookmarksURL[entryIndex], bookURLList[entryIndex]);
	}

	/* Copy history list into WapData structure */

	WapData->no_of_history = no_of_history;

	for (entryIndex = 0; entryIndex<no_of_history; entryIndex++)
	{
		sprintf(number,"%2d. ",entryIndex+1);			/* store number	*/
		ATB_char_to_uc(WapData->History[entryIndex], number);
		ATB_char_to_uc(&WapData->History[entryIndex][NUMBER_PADDING], historyList[entryIndex]);
		strcpy(WapData->HistoryURL[entryIndex], histURLList[entryIndex]);
	}

	/* Copy profile data into WapData and WapProfilesData structures */

	WapData->no_of_profiles    = no_of_profiles;

	for (profile = 0; profile<no_of_profiles; profile++)
	{
		ATB_char_to_uc(WapProfilesData->Profile[profile].Title, profilesDefault[profile]);
		strcpy(WapProfilesData->Profile[profile].Homepage, homepageURL[profile]);

		WapProfilesData->Profile[profile].ConnectionType = WAP_CONTINUOUS;
		WapProfilesData->Profile[profile].ConnectionSpeed = ConnectionSpeed[profile];  /* SPR#1827 - SH - Assign connection speed values */
		WapProfilesData->Profile[profile].Security	= FALSE;
		WapProfilesData->Profile[profile].AccessType     = AccessType[profile]; /* SPR#1189 - SH - Now correctly assigned*/
		WapProfilesData->Profile[profile].ResponseTimer  = ResponseTimer[profile];
		WapProfilesData->Profile[profile].Port1		= Port1[profile];
		WapProfilesData->Profile[profile].Port2		= Port2[profile];
		strcpy(WapProfilesData->Profile[profile].IPAddress1, IPAddress1[profile]);
		strcpy(WapProfilesData->Profile[profile].IPAddress2, IPAddress2[profile]);
		strcpy(WapProfilesData->Profile[profile].DialupNumber, DialupNumber[profile]);
		strcpy(WapProfilesData->Profile[profile].APN, APN[profile]);
		strcpy(WapProfilesData->Profile[profile].Username, Username[profile]);
		strcpy(WapProfilesData->Profile[profile].Password, Password[profile]);
//xpradipg - Aug 4: changes for the WAP2.0: Populating the default values

		strcpy(WapProfilesData->Profile[profile].NameServer1, NameServer1[profile]);
		strcpy(WapProfilesData->Profile[profile].NameServer2, NameServer2[profile]);
		WapProfilesData->Profile[profile].PPGAuthentication=PPGAuthentication[profile];
		WapProfilesData->Profile[profile].WirelessProfiledHTTP=WirelessProfiledHTTP[profile];

	}

	/* Write data to flash */

	if (flash_wap_write()==EFFS_OK)												// Make sure flash data is written OK
		return WAP_OK;
	else
		return WAP_FAIL;
}


void ATB_wap_profile_default(UBYTE ProfileId)
{
 char  *profilesDefault[]  = { "fg.vip.gprs", "vip.gprs", "fg.ht.gprs", "ht.gprs", "D1.gprs", "D2.gprs", "E-Plus.gprs", "O2.gprs", "Empty"};
 char *homepageURL[]  = { "http://wap.fgmicrotec.hr", "http://wap.vip.hr", "http://wap.fgmicrotec.hr", "http://wap.fgmicrotec.hr", "http://wap.yahoo.com", "http://wap.yahoo.com",  "http://wap.yahoo.com", "http://wap.yahoo.com", "http://wap.yahoo.com"};
 UBYTE ConnectionSpeed[] = { WAP_ISDN9600,    WAP_ISDN9600,   WAP_ISDN9600,    WAP_ISDN9600,    WAP_ISDN9600,    WAP_ISDN9600,     WAP_ISDN9600,    WAP_ISDN9600,   WAP_ISDN9600};

 UBYTE AccessType[]   = { WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_GPRS_DATA, WAP_CS_DATA};

 USHORT ResponseTimer[]  = {60, 60, 60, 60, 60, 60, 60, 60, 60};
 USHORT Port1[]    = {9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201};
 USHORT Port2[]    = {9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201, 9201};
 char *IPAddress1[]   = { "217.014.220.081",   "212.091.099.091",  "217.014.220.081",   "010.012.000.003",   "193.254.160.002",   "139.007.029.001",    "212.023.097.009",   "195.182.114.052",   "000.000.000.000"};
 char *IPAddress2[]   = { "217.014.220.081",   "212.091.099.091",  "217.014.220.081",   "000.000.000.000",   "193.254.160.002",   "139.007.029.001",    "212.023.097.009",   "195.182.114.052",   "000.000.000.000"};
 char *DialupNumber[]  = { "00448704290000",   "00448704290000", "00448704290000",  "00448704290000",  "17266",     "00491722290100",   "00448456609561",  "00448456609561",  ""};
 char *APN[]    = { "gprs5.vipnet.hr",   "gprs5.vipnet.hr",  "www.htgprs.hr",   "www.htgprs.hr",   "wap.t-d1.de",   "wap.vodafone.de",    "wap.eplus.de",   "wap.viaginterkom.de", ""};
 char *Username[]   = { "38591",     "38591",    "",       "",       "t-d1",     "",        "eplus",    "",      ""};
 char *Password[]   = { "38591",     "38591",    "",       "",       "wap",     "",        "wap",     "",      ""};

  ATB_char_to_uc(WapProfilesData->Profile[ProfileId].Title, profilesDefault[ProfileId]);
  strcpy(WapProfilesData->Profile[ProfileId].Homepage, homepageURL[ProfileId]);
   WapProfilesData->Profile[ProfileId].ConnectionType = WAP_CONTINUOUS;
  WapProfilesData->Profile[ProfileId].ConnectionSpeed = ConnectionSpeed[ProfileId];  /* SPR#1827 - SH - Assign connection speed values */
  WapProfilesData->Profile[ProfileId].Security = FALSE;
  WapProfilesData->Profile[ProfileId].AccessType     = AccessType[ProfileId]; /* SPR#1189 - SH - Now correctly assigned*/
  WapProfilesData->Profile[ProfileId].ResponseTimer  = ResponseTimer[ProfileId];
  WapProfilesData->Profile[ProfileId].Port1  = Port1[ProfileId];
  WapProfilesData->Profile[ProfileId].Port2  = Port2[ProfileId];
  strcpy(WapProfilesData->Profile[ProfileId].IPAddress1, IPAddress1[ProfileId]);
  strcpy(WapProfilesData->Profile[ProfileId].IPAddress2, IPAddress2[ProfileId]);
  strcpy(WapProfilesData->Profile[ProfileId].DialupNumber, DialupNumber[ProfileId]);
  strcpy(WapProfilesData->Profile[ProfileId].APN, APN[ProfileId]);
  strcpy(WapProfilesData->Profile[ProfileId].Username, Username[ProfileId]);
  strcpy(WapProfilesData->Profile[ProfileId].Password, Password[ProfileId]);
 return;

}


#else

T_WAP_RES ATB_wap_profile_default_create(UBYTE only_reset_profiles)
{
	UBYTE	no_of_bookmarks		= 10;
	char	*bookmarksList[] =
	{
		"Yahoo!",
		"AOL",
		"O2",
		"Financial Times",
		"Cnet tech news",
		"T-Mobile UK",
		"Ents24",
		"WEB.DE",
		"Vizzavi",
		"El Pais"
	};

	char 	*bookURLList[]	=
	{
		"http://wap.yahoo.com",
		"http://wap.aol.co.uk",
		"http://wap.o2.co.uk/",
		"http://wap.ft.com",
		"http://wap.cnet.com",
		"http://wap.t-mobile.co.uk",
		"http://wap.ents24.co.uk",
		"http://wap.web.de",
		"http://wap.vizzavi.co.uk",
		"http://wap.elpais.es"
	};

	UBYTE	no_of_history		= 0;
	char	*historyList[]		= { "dummy" };
	char	*histURLList[]		= { "www.dummy.org" };

/* SPR#2324 - SH
 * - Only need 3 profiles now, as extra ones can be added by user
 * - Only create first 2 if there's no GPRS */
#ifdef GPRS
	UBYTE	no_of_profiles	= 3;
#else
	UBYTE	no_of_profiles	= 2;
#endif

	char 	*profilesDefault[] 	= { "Breathe", "Vodaf.CSD", "Vodaf.GPRS", "Empty", "Empty"};
	char	*homepageURL[]		= { "http://wap.yahoo.com", "http://wap.yahoo.com", "http://wap.yahoo.com", "http://wap.yahoo.com", "http://wap.yahoo.com"};
	char	*IPAddress1[]		= { "062.024.128.014", "212.183.137.012", "212.183.137.012", "000.000.000.000", "000.000.000.000"};
	char	*IPAddress2[]		= { "062.024.128.014", "212.001.130.132", "212.001.130.132", "000.000.000.000", "000.000.000.000"};
	char	*DialupNumber[]		= { "00448704290000", "00447836900808", "00448456609561", "", "" };
	char	*APN[]				= { "none", "none", "wap.vodafone.co.uk", "", ""};
	char	*Username[]			= { "breathe", "user@vodafone.net", "user@vodafone.net", "", "" };
	char	*Password[]			= { "breathewap", "user", "user", "", ""};
	UBYTE AccessType[]			= { WAP_CS_DATA, WAP_CS_DATA, WAP_GPRS_DATA, WAP_CS_DATA, WAP_CS_DATA };

	/* SPR#2324 - SH - Some defaults moved to ATB_wap_profile_default */
	USHORT entryIndex;
	USHORT	profile;
	char number[NUMBER_PADDING+1];

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_default_create");
#endif

	WapData->ProfileId		= 0;

	/* SPR#2324 - SH - If this flag is set, don't reset settings and bookmarks */

	if (!only_reset_profiles)
	{
		WapData->Status	= WAP_STATUS_SAVEHISTORY | WAP_STATUS_SCALEIMAGES;

		/* Copy bookmarks into WapData structure */

		WapData->no_of_bookmarks = no_of_bookmarks;

		for (entryIndex = 0; entryIndex<no_of_bookmarks; entryIndex++)
		{
			ATB_char_to_uc(WapData->Bookmarks[entryIndex], bookmarksList[entryIndex]);
			strcpy(WapData->BookmarksURL[entryIndex], bookURLList[entryIndex]);
		}

		/* Copy history list into WapData structure */

		WapData->no_of_history = no_of_history;

		for (entryIndex = 0; entryIndex<no_of_history; entryIndex++)
		{
			sprintf(number,"%2d. ",entryIndex+1);			/* store number	*/
			ATB_char_to_uc(WapData->History[entryIndex], number);
			ATB_char_to_uc(&WapData->History[entryIndex][NUMBER_PADDING], historyList[entryIndex]);
			strcpy(WapData->HistoryURL[entryIndex], histURLList[entryIndex]);
		}
	}

	/* Copy profile data into WapData and WapProfilesData structures */

	WapData->no_of_profiles    = no_of_profiles;

	for (profile = 0; profile<MAX_PROFILES; profile++)
	{
		/* SPR#2324 - SH - Set up "blank" profile first, then configure
		 * WAP gateway settings */

		ATB_wap_profile_default(profile);
		if (profile<no_of_profiles)
		{
			ATB_char_to_uc(WapProfilesData->Profile[profile].Title, profilesDefault[profile]);
			strcpy(WapProfilesData->Profile[profile].Homepage, homepageURL[profile]);
			WapProfilesData->Profile[profile].AccessType = AccessType[profile];
			strcpy(WapProfilesData->Profile[profile].IPAddress1, IPAddress1[profile]);
			strcpy(WapProfilesData->Profile[profile].IPAddress2, IPAddress2[profile]);
			strcpy(WapProfilesData->Profile[profile].DialupNumber, DialupNumber[profile]);
			strcpy(WapProfilesData->Profile[profile].APN, APN[profile]);
			strcpy(WapProfilesData->Profile[profile].Username, Username[profile]);
			strcpy(WapProfilesData->Profile[profile].Password, Password[profile]);
		}
	}

	/* Write data to flash */

	if (flash_wap_write()==EFFS_OK)		/* Make sure flash data is written OK */
		return WAP_OK;
	else
		return WAP_FAIL;
}

/*******************************************************************************

 $Function:    	ATB_wap_profile_default

 $Description:	Sends the configuration information of the current profile to the WAP task.
 				SPR#2324 - SH - Added

 $Returns:		None.

 $Arguments:	ProfileId - Profile identifier

*******************************************************************************/

void ATB_wap_profile_default(UBYTE ProfileId)
{
	AUI_wap_stringID(WapProfilesData->Profile[ProfileId].Title, CARD_TITLE_MAX_LEN, WAP_STRING_UNTITLED);
	strcpy(WapProfilesData->Profile[ProfileId].Homepage, "");
	WapProfilesData->Profile[ProfileId].ConnectionType = WAP_TEMPORARY;
	WapProfilesData->Profile[ProfileId].ConnectionSpeed = WAP_ANALOGUE;  /* SPR#1827 - SH - Assign connection speed values */
	WapProfilesData->Profile[ProfileId].Security	= FALSE;
	WapProfilesData->Profile[ProfileId].AccessType     = WAP_GPRS_DATA; /* SPR#1189 - SH - Now correctly assigned*/
	WapProfilesData->Profile[ProfileId].ResponseTimer  = WAP_DEFAULT_RESPONSE_TIME;
	WapProfilesData->Profile[ProfileId].Port1		= WAP_DEFAULT_PORT;
	WapProfilesData->Profile[ProfileId].Port2		= WAP_DEFAULT_PORT;
	strcpy(WapProfilesData->Profile[ProfileId].IPAddress1, "000.000.000.000");
	strcpy(WapProfilesData->Profile[ProfileId].IPAddress2, "000.000.000.000");
	strcpy(WapProfilesData->Profile[ProfileId].DialupNumber, "");
	strcpy(WapProfilesData->Profile[ProfileId].APN, "");
	strcpy(WapProfilesData->Profile[ProfileId].Username, "");
	strcpy(WapProfilesData->Profile[ProfileId].Password, "");

	return;
}

#endif

#if defined (FF_MMI_MMS) && defined (FF_GPF_TCPIP)
T_WAP_RES ATB_mms_profile_default_create()
{
	UBYTE	no_of_profiles	= 8;
	USHORT	profile;
	char		*MmscAddress[] = { "http://mms.fgmicrotec.hr:8888/mms=fgmicro", "http://mms.vipnet.hr/servlets/mms", "http://mms.fgmicrotec.hr:8888/mms=fgmicro", "http://mms.htmobile.hr/servlets/mms", "http://mms.t-mobile.de/servlets/mms", "http://139.7.24.1/servlets/mms", "http://mms/eplus", "http://10.81.0.7:8002"};

	/* Copy profile data into MmsProfilesData structures */
	for (profile = 0; profile<no_of_profiles; profile++)
	{
		strcpy(MmsProfilesData->Profile[profile].MmscAddress, MmscAddress[profile]);
	}

	/* Write data to flash */
	if (flash_mms_write()==EFFS_OK)												// Make sure flash data is written OK
		return WAP_OK;
	else
		return WAP_FAIL;
}
#endif

/*******************************************************************************

 $Function:    	ATB_wap_profile_send

 $Description:	Sends the configuration information of the current profile to the WAP task.

 $Returns:		None.

 $Arguments:	View  - the current view

*******************************************************************************/

#ifdef FF_GPF_TCPIP
#if 0
void ATB_wap_profile_send(T_WAP_VIEW *View)
{
	T_WAP_PROFILE		*Profile = View->Profile;
	ULONG				IPAddressLong;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_send");
#endif

	/* Set bearer for data channel */
	switch(Profile->AccessType)
	{
		case WAP_GPRS_DATA:
			ATB_wap_conn_config_int(View, configACCESS_TYPE, BEARER_GSM_GPRS);
			break;
		case WAP_CS_DATA:
			ATB_wap_conn_config_int(View, configACCESS_TYPE, BEARER_GSM_CSD);
			break;
		case WAP_SMS:
			ATB_wap_conn_config_int(View, configACCESS_TYPE, BEARER_GSM_SMS);
			break;
	}

	/* Setup timeout */
	ATB_wap_conn_config_int(View, configTIMEOUT, Profile->ResponseTimer);
	/* Setup stack mode */
	/* This part is used only for browser */
	if (View->object_id == 1)
	{
		if (Profile->Port1 == 9201)
		{
			ATB_wap_conn_config_int(View, configCONNECTION_TYPE, CONNECTION_TYPE_WSP_CO);
			TRACE_EVENT("CONNECTION_TYPE_WSP_CO at the location 1 called");
		}
		else
		{
			ATB_wap_conn_config_int(View, configCONNECTION_TYPE, CONNECTION_TYPE_TCP);
			TRACE_EVENT("CONNECTION_TYPE_TCP at the location 1 called");
		}
	}

	if( (Profile->WirelessProfiledHTTP) || (Profile->Port1 == 9201) )
	{
	/* Set IP address
	 * Trying first IP address, so set flag accordingly */
	View->secondaryIP = FALSE;
	ATB_conv_str_to_IP(Profile->IPAddress1, strlen(Profile->IPAddress1), &IPAddressLong);
	ATB_wap_conn_config_str(View, configPROXY_ADDRESS, (CHAR *)&IPAddressLong, sizeof(ULONG));
	}

	// Config security
	ATB_wap_conn_config_int(View, configALWAYS_SECURE, 0);
	ATB_wap_conn_config_int(View, configNEVER_SECURE, 1);

	/* Set WAP host */
	//ATB_wap_conn_config_str(View, configADD_HOST, Profile->Homepage, strlen(Profile->Homepage));

	/* Set connection port 1 */
	ATB_wap_conn_config_int(View, configPROXY_PORT, Profile->Port1);
	ATB_wap_conn_config_int(View, WAP_setPort1, Profile->Port1);
	ATB_wap_conn_config_int(View, configPROXY_SECURE_PORT, 0);

	/* Set connection port 2 */
	ATB_wap_conn_config_int(View, WAP_setPort2, Profile->Port2);

	// Set proxy credentials
	ATB_wap_conn_config_str(View, WAP_transLongIP, (char*) &IPAddressLong, 4);
	ATB_wap_conn_config_str(View, WAP_transUsername, Profile->Username, strlen(Profile->Username));
	ATB_wap_conn_config_str(View, WAP_transPassword, Profile->Password, strlen(Profile->Password));


	/* SPR#2086 - SH - Set connection port for PUSH */
//	ATB_wap_conn_config_int(View, WAP_setPortPush, WAP_DEFAULT_PORT_PUSH); FG ?


	return;
}
#else

// xreddymn Jun-21-2005 MMI-SPR-30291: Changed method of sending WAP profile
// from MMI to WAP adapter.

extern void *micAlloc(int size);

void ATB_wap_profile_send(T_WAP_VIEW *View)
{
	T_WAP_PROFILE				*Profile = View->Profile;
	ULONG						IPAddressLong;
	T_MMI_WAP_PROFILE_DATA		*profile_data;
	T_MMI_WAP_SEND_PROFILE_IND	send_profile_ind;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_send");
#endif

	profile_data = micAlloc(sizeof(T_MMI_WAP_PROFILE_DATA));
	if(profile_data == NULL)
	{
		return;
	}

	/* Set bearer for data channel */
	switch(Profile->AccessType)
	{
		case WAP_GPRS_DATA:
			profile_data->configACCESS_TYPE = BEARER_GSM_GPRS;
			break;
		case WAP_CS_DATA:
			profile_data->configACCESS_TYPE = BEARER_GSM_CSD;
			break;
		case WAP_SMS:
			profile_data->configACCESS_TYPE = BEARER_GSM_SMS;
			break;
	}

	/* Setup timeout */
	profile_data->configTIMEOUT = Profile->ResponseTimer;
	ATB_wap_conn_config_int(View, configTIMEOUT, Profile->ResponseTimer);

	/* Setup stack mode */
	/* This part is used only for browser */
	profile_data->configCONNECTION_TYPE = -1;
	if (View->object_id == 1)
	{
		if (Profile->Port1 == 9201)
		{
			profile_data->configCONNECTION_TYPE = CONNECTION_TYPE_WSP_CO;
			TRACE_EVENT("CONNECTION_TYPE_WSP_CO at the location 1 called");
		}
		else
		{
			profile_data->configCONNECTION_TYPE = CONNECTION_TYPE_TCP;
			TRACE_EVENT("CONNECTION_TYPE_TCP at the location 1 called");
		}
	}

	profile_data->configPROXY_ADDRESS[0] = 0;
	if( (Profile->WirelessProfiledHTTP) || (Profile->Port1 == 9201) )
	{
		/* Set IP address
		 * Trying first IP address, so set flag accordingly */
		View->secondaryIP = FALSE;
		ATB_conv_str_to_IP(Profile->IPAddress1, strlen(Profile->IPAddress1), &IPAddressLong);
		memcpy(profile_data->configPROXY_ADDRESS, (CHAR *)&IPAddressLong, sizeof(ULONG));
	}

	// Config security
	profile_data->configALWAYS_SECURE = 0;
	profile_data->configNEVER_SECURE = 1;

	/* Set connection port 1 */
	profile_data->configPROXY_PORT = Profile->Port1;
	profile_data->WAP_setPort1 = Profile->Port1;
	profile_data->configPROXY_SECURE_PORT = 0;

	/* Set connection port 2 */
	profile_data->WAP_setPort2 = Profile->Port2;

	// Set proxy credentials
	memcpy(profile_data->WAP_transLongIP, (CHAR *)&IPAddressLong, sizeof(ULONG));
	strncpy(profile_data->WAP_transUsername, Profile->Username, 20);
	strncpy(profile_data->WAP_transPassword, Profile->Password, 20);

	send_profile_ind.data = (UBYTE*)profile_data;
	send_profile_ind.object_id = View->object_id;
	send_profile_ind.channel_id = View->channel;
	M_MMI_WAP_SEND_PROFILE_IND(&send_profile_ind);

	return;
}

#endif
#else /* #ifdef FF_GPF_TCPIP */

void ATB_wap_profile_send(T_WAP_VIEW *View)
{
	T_WAP_PROFILE		*Profile = View->Profile;
	ULONG				IPAddressLong;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_send");
#endif

	/* Set bearer for data channel */
	switch(Profile->AccessType)
	{
		case WAP_GPRS_DATA:
			ATB_wap_conn_config_int(View, configACCESS_TYPE, BEARER_GSM_GPRS);
			break;
		case WAP_CS_DATA:
			ATB_wap_conn_config_int(View, configACCESS_TYPE, BEARER_GSM_CSD);
			break;
		case WAP_SMS:
			ATB_wap_conn_config_int(View, configACCESS_TYPE, BEARER_GSM_SMS);
			break;
	}

	/* Setup timeout */
	ATB_wap_conn_config_int(View, configTIMEOUT, Profile->ResponseTimer);

	/* Set IP address
	 * Trying first IP address, so set flag accordingly */
	View->secondaryIP = FALSE;
	ATB_conv_str_to_IP(Profile->IPAddress1, strlen(Profile->IPAddress1), &IPAddressLong);
	ATB_wap_conn_config_str(View, configUDP_IP_GW, (CHAR *)&IPAddressLong, sizeof(ULONG));

	/* Set WAP Server Authentification name */
	ATB_wap_conn_config_str(View, configAUTH_ID_GW, Profile->Username, strlen(Profile->Username));

	/* Set WAP Server Authentification password */
	ATB_wap_conn_config_str(View, configAUTH_PASS_GW, Profile->Password, strlen(Profile->Password));

	/* Set WAP host */
	ATB_wap_conn_config_str(View, configADD_HOST, Profile->Homepage, strlen(Profile->Homepage));

	/* Set connection port 1 */
	ATB_wap_conn_config_int(View, WAP_setPort1, Profile->Port1);

	/* Set connection port 2 */
	ATB_wap_conn_config_int(View, WAP_setPort2, Profile->Port2);

	return;
}

#endif /* !#ifdef FF_GPF_TCPIP */

#ifdef FF_GPF_TCPIP
/*******************************************************************************

 $Function:    	ATB_wap_profile_setting_get

 $Description:	Returns the status of a particular setting

 $Returns:		1 if the setting is on, 0 otherwise

 $Arguments:	The setting to check

*******************************************************************************/

UBYTE ATB_wap_profile_setting(UBYTE setting)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_setting_get");
#endif

	if (WapData->Status & setting)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


/*******************************************************************************

 $Function:    	ATB_wap_profile_setting_change

 $Description:	Switches a setting on or off

 $Returns:		None

 $Arguments:	setting - The setting to change
 				value - The new value (1 = on, 0 = off)

*******************************************************************************/

void ATB_wap_profile_setting_change(UBYTE setting, UBYTE value)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_profile_setting_get");
#endif

	if (value)
	{
		WapData->Status ^= setting;
	}
	else
	{
		WapData->Status &= ~setting;
	}
	return;
}

/*******************************************************************************

 $Function:    	ATB_wap_profile_add

 $Description:	Add a new profile with the given data

 $Returns:		none

 $Arguments:	p: Points to the structure containing the new profile data

 				xreddymn Jan-20-2005 MMI-SPR-28135: WAP_OTA

*******************************************************************************/

void ATB_wap_profile_add(T_WAP_PROFILE *p)
{
	if (WapData->no_of_profiles==MAX_PROFILES)
	{
		/* Overwrite currently selected profile. But the correct method would be:
		 * Ask user if the currently selected profile can be overwritten
		 */
		memcpy(&WapProfilesData->Profile[WapData->ProfileId],p,sizeof(T_WAP_PROFILE));
		flash_wap_write();
	}
	else
	{
		memcpy(&WapProfilesData->Profile[WapData->no_of_profiles],p,sizeof(T_WAP_PROFILE));
		WapData->ProfileId=WapData->no_of_profiles;
		WapData->no_of_profiles++;
		flash_wap_write();
	}
#if(0)
	if (View_header!=NULL)
	{
		ATB_wap_entry_list_destroy(View_header->ProfilesList);
		View_header->ProfilesList = ATB_wap_entry_list_create(WAP_PROFILES_LIST, MAX_PROFILES, PROFILENAME_MAX_LEN, TRUE);
	}
#endif
	AUI_profile_list_redraw(WapData->ProfileId);
}

#endif
/*******************************************************************************

 $Function:    	ATB_wap_secondary_IP

 $Description:	SPR#1688 - SH - Added this function
 				If first IP address fails, try using secondary one.

 $Returns:		None.

 $Arguments:	View  - the current view

*******************************************************************************/

void ATB_wap_secondary_IP(T_WAP_VIEW *View)
{
	ULONG IPAddressLong;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_secondary_IP()");
#endif

	/* We're now using secondary IP */

	View->secondaryIP = TRUE;

	/* Send IP configuration to WAP browser */

	ATB_conv_str_to_IP(View->Profile->IPAddress2, strlen(View->Profile->IPAddress2), &IPAddressLong);
#ifdef FF_GPF_TCPIP
	ATB_wap_conn_config_str(View, configPROXY_ADDRESS, (CHAR *)&IPAddressLong, sizeof(ULONG));
#else
	ATB_wap_conn_config_str(View, configUDP_IP_GW, (CHAR *)&IPAddressLong, sizeof(ULONG));
#endif


	/* Reload the requested page */

	ATB_wap_download_url(View, View->URL, TRUE);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_entry_list_create

 $Description:	Creates an entries list

 $Returns:		Pointer to entry list

 $Arguments:	type		- type of list
 				max_entries	- maximum number of entries in list
 				entry_size	- size of entries in characters
 				unicode		- TRUE if entries are unicode

*******************************************************************************/

T_WAP_LIST * ATB_wap_entry_list_create(WAP_LIST_TYPE type, UBYTE max_entries, UBYTE entry_size, BOOL unicode)
{
	T_WAP_LIST *EntryList;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_entry_list_create");
#endif

	/* Allocate memory */

	EntryList  			= (T_WAP_LIST *)AUI_wap_memory_alloc(sizeof(T_WAP_LIST));
	EntryList->Entry	= (char **)AUI_wap_memory_alloc(max_entries*sizeof(char*));

	/* Assign list parameters */

	EntryList->type		= type;
	EntryList->max_entries = max_entries;
	EntryList->entry_size  = entry_size;
	EntryList->no_of_entries = 0;
	EntryList->unicode	= unicode;

	return EntryList;
}


/*******************************************************************************

 $Function:    	ATB_wap_entry_list_destroy

 $Description:	Destroys an entries list

 $Returns:		WAP_OK
 				WAP_FAIL if list does not exist

 $Arguments:	EntryList	- pointer to entry list data

*******************************************************************************/

T_WAP_RES ATB_wap_entry_list_destroy(T_WAP_LIST *EntryList)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("AUI_wap_entry_list_destroy");
#endif

	/* Ensure list exists */

	if (EntryList==NULL)
		return WAP_FAIL;

	/* Destroy structure */

	AUI_wap_memory_free((UBYTE *)EntryList->Entry, EntryList->max_entries*sizeof(char *));
	AUI_wap_memory_free((UBYTE *)EntryList,sizeof(T_WAP_LIST));

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_entry_add

 $Description:	Adds an entry to an entry list

 $Returns:		WAP_OK if added successfully
 				WAP_FAIL if the list is full

 $Arguments:	Entrylist	- Pointer to entries table
 				Entry		- Entry to add

*******************************************************************************/

T_WAP_RES ATB_wap_entry_add(T_WAP_LIST *EntryList, char *Entry)
{
	UBYTE entryIndex = EntryList->no_of_entries;	/* Where the new entry should go */

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_entry_add");
	ATB_trace_string(Entry, strlen(Entry));
#endif

	/* Check if the list is full */

	if (entryIndex==EntryList->max_entries)
		return WAP_FAIL;

	/* Add the entry */

	if (EntryList->unicode)
	{
		ATB_uc_text_copy((USHORT *)EntryList->Entry[entryIndex], (USHORT *)Entry, EntryList->entry_size);
		// xreddymn Jan-06-2005 MMI-SPR-27618: Added End Of String character
		*((USHORT *)((USHORT *)EntryList->Entry[entryIndex]+EntryList->entry_size))='\0';
	}
	else
	{
		strncpy(EntryList->Entry[entryIndex], Entry, EntryList->entry_size);
		// xreddymn Jan-06-2005 MMI-SPR-27618: Added End Of String character
		*((char *)((char *)EntryList->Entry[entryIndex]+EntryList->entry_size))='\0';
	}

	EntryList->no_of_entries++;		/* Increase list count */

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_entry_change

 $Description:	Changes an entry in an entry list, destroying the old entry and
 				creating a new one.

 $Returns:		WAP_OK

 $Arguments:	Entrylist 		- Pointer to entries table
 				Entry			- New entry text
 				entryIndex		- Number of entry to change

*******************************************************************************/

#ifdef FF_GPF_TCPIP
T_WAP_RES ATB_wap_entry_change(WAP_LIST_TYPE type, T_WAP_LIST *EntryList, char *Entry, UBYTE entryIndex)
#else
T_WAP_RES ATB_wap_entry_change(T_WAP_LIST *EntryList, char *Entry, UBYTE entryIndex)
#endif

{
	char number[NUMBER_PADDING+1];
	USHORT *EntryUC;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_entry_change");
#endif

#ifdef FF_GPF_TCPIP
	if (type==WAP_HISTORY_LIST)
#else
	if (EntryList->type==WAP_HISTORY_LIST)
#endif
	{
		sprintf(number, "%2d. ", entryIndex+1);			/* Add "xx. " number at start */

		if (EntryList->unicode)
		{
			EntryUC = (USHORT *)EntryList->Entry[entryIndex];
			ATB_char_to_uc(EntryUC, number);
			ATB_uc_text_copy(&EntryUC[NUMBER_PADDING], (USHORT *)Entry, EntryList->entry_size-NUMBER_PADDING);
		}
		else
		{
			strcpy(EntryList->Entry[entryIndex], number);
			strncpy(&EntryList->Entry[entryIndex][NUMBER_PADDING], Entry, EntryList->entry_size-NUMBER_PADDING);
		}
	}
	else
	{
		/* SPR#1816 - SH - Modified for unicode */

		if (EntryList->unicode)
		{
			ATB_uc_text_copy((USHORT *)EntryList->Entry[entryIndex], (USHORT *)Entry, EntryList->entry_size);
		}
		else
		{
			strncpy(EntryList->Entry[entryIndex], Entry, EntryList->entry_size);
		}
	}

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_entry_insert

 $Description:	Insert an entry into an entry list, shifting all subsequent entries up one.
 				If the maximum limit of the entry list is reached, the last entry is
 				deleted.

 $Returns:		WAP_OK if inserted successfully
 				WAP_FAIL if list is full, or if request does not make sense

 $Arguments:	Entrylist 		- Pointer to entries table
 				Entry			- Entry to insert
 				entryIndex 		- Position at which to insert the new entry

*******************************************************************************/

#ifdef FF_GPF_TCPIP
T_WAP_RES ATB_wap_entry_insert(WAP_LIST_TYPE type, T_WAP_LIST *EntryList, char *Entry, UBYTE entryIndex)
#else
T_WAP_RES ATB_wap_entry_insert(T_WAP_LIST *EntryList, char *Entry, UBYTE entryIndex)
#endif
{
	USHORT entryIndex2 = EntryList->no_of_entries;
	USHORT *EntryUC;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_entry_insert()");
#endif

	/* Check for errors */

	if (EntryList==NULL || entryIndex>EntryList->no_of_entries
		|| EntryList->no_of_entries>EntryList->max_entries)
	{
		return WAP_FAIL;
	}

	/* xreddymn Dec-10-2004 MMI-SPR-26159: Duplicate check for history list */
#ifdef FF_GPF_TCPIP

// If set to 0, will allow duplicate entries in the History List
	if(type==WAP_URL_LIST)
	{
		S32 	i, length;
		BOOL	already_exists=FALSE;

		if (EntryList->unicode)
		{
			length=ATB_uc_text_len((USHORT*)Entry);
			for(i=0;i<entryIndex2;i++)
			{
				if(ATB_uc_text_compare((USHORT*)EntryList->Entry[i],(USHORT*)Entry,length)==0)
				{
					already_exists=TRUE;
					break;
				}
			}
		}
		else
		{
//			length=strlen((const char*)Entry);
			for(i=0;i<entryIndex2;i++)
			{
				if(strcmp((const char*)EntryList->Entry[i],(const char*)Entry)==0)
				{
					already_exists=TRUE;
					break;
				}
			}
		}
		if(already_exists==TRUE)
		{
			return WAP_FAIL;
		}
	}
#endif

	if (EntryList->no_of_entries == EntryList->max_entries)  /* If the list is full... */
	{
		entryIndex2--;									/* Start shifting from second last entry */
	}
	else
	{
		EntryList->no_of_entries++;						/* Increase bookmark count */
	}

	while (entryIndex2>entryIndex)						/* Work back from end of table */
	{
		/* Shift the table down to make space */

		if (EntryList->unicode)
		{
			ATB_uc_text_copy((USHORT *)EntryList->Entry[entryIndex2],
				(USHORT *)EntryList->Entry[entryIndex2-1],
				EntryList->entry_size);
		}
		else
		{
			strncpy(EntryList->Entry[entryIndex2],
				EntryList->Entry[entryIndex2-1],
				EntryList->entry_size);
		}

		entryIndex2--;
	}

	/* For history list, need to include space for number at start */

#ifdef FF_GPF_TCPIP
	if (type==WAP_HISTORY_LIST)													// For history list, need to include space for number at start
#else
	if (EntryList->type==WAP_HISTORY_LIST)
#endif
	{
		if (EntryList->unicode)
		{
			EntryUC = (USHORT *)EntryList->Entry[entryIndex];
			ATB_uc_text_copy(&EntryUC[NUMBER_PADDING],
				(USHORT *)Entry,
				EntryList->entry_size-NUMBER_PADDING);
		}
		else
		{
			strncpy(&EntryList->Entry[entryIndex][NUMBER_PADDING],
				Entry,
				EntryList->entry_size-NUMBER_PADDING);
		}
		ATB_wap_renumber_history(EntryList);
	}
	else
	{
		/* SPR#1816 - SH - Modified for unicode */

		if (EntryList->unicode)
		{
			ATB_uc_text_copy((USHORT *)EntryList->Entry[entryIndex],
				(USHORT *)Entry,
				EntryList->entry_size);
		}
		else
		{
			strncpy(EntryList->Entry[entryIndex],
				Entry,
				EntryList->entry_size);
		}
	}

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_entry_remove

 $Description:	Removes an entry from the bookmarks or history list and moves
 				other entries up to close the gap.

 $Returns:		WAP_OK if entry successfully removed
 				WAP_FAIL if request does not make sense

 $Arguments:	Entrylist 		- Pointer to entries table
 				entryIndex 		- Number of the entry to delete

*******************************************************************************/

T_WAP_RES ATB_wap_entry_remove(T_WAP_LIST *EntryList, UBYTE entryIndex)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_entry_remove");
#endif

	/* Make sure request is meaningful */

	if (EntryList==NULL || entryIndex>EntryList->no_of_entries)
	{
		return WAP_FAIL;
	}

	EntryList->no_of_entries--;	/* Decrease list count */

	while (entryIndex<(EntryList->no_of_entries))
	{
			/* If we haven't reached end of table, move entries up */

		if (EntryList->unicode)
		{
			ATB_uc_text_copy((USHORT *)EntryList->Entry[entryIndex],
				(USHORT *)EntryList->Entry[entryIndex+1],
				EntryList->entry_size);
		}
		else
		{
			strncpy(EntryList->Entry[entryIndex],
				EntryList->Entry[entryIndex+1],
				EntryList->entry_size);
		}
		entryIndex++;
	}

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_entry_remove_all

 $Description:	Removes all entries from a Entry List

 $Returns:		WAP_OK if successful
 				WAP_FAIL if entry list does not exist

 $Arguments:	EntryList 	- Pointer to bookmarks table

*******************************************************************************/

T_WAP_RES ATB_wap_entry_remove_all(T_WAP_LIST *EntryList)
{
	UBYTE entryIndex;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_entry_remove_all");
#endif

	/* Make sure request is meaningful */
	if (EntryList==NULL)
	{
		return WAP_FAIL;
	}

	EntryList->no_of_entries = 0;
	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_renumber_history

 $Description:	Renumber history list, changing prefixes to all entries

 $Returns:		WAP_OK

 $Arguments:	EntryList - pointer to history list

*******************************************************************************/

#ifdef FF_GPF_TCPIP
int ATB_wap_renumber_history(T_WAP_LIST *EntryList)
#else
T_WAP_RES ATB_wap_renumber_history(T_WAP_LIST *EntryList)
#endif
{
	UBYTE entryIndex;
	char number[NUMBER_PADDING+1];
	USHORT *EntryUC;

#ifdef TRACE_AUIWAP
	TRACE_FUNCTION("ATB_wap_renumber_history");
#endif

	for (entryIndex = 0; entryIndex<(EntryList->no_of_entries); entryIndex++)
	{
		sprintf(number, "%2d.", entryIndex+1);			/* Add "xx. " number at start */

		if (EntryList->unicode)
		{
			EntryUC = (USHORT *)EntryList->Entry[entryIndex];
			ATB_char_to_uc(EntryUC, number);
			/* Overwrite terminating 0 after prefix with space */
			EntryUC[NUMBER_PADDING-1] = (USHORT)(' '<<8);
		}
		else
		{
			/* Overwrite the number prefix */
			strcpy(EntryList->Entry[entryIndex],number);
			/* Overwrite terminating 0 after prefix with space */
			EntryList->Entry[entryIndex][NUMBER_PADDING-1] = ' ';
		}
	}

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_status_change

 $Description:	Called to change WAP Application status, i.e. downloading, updating, etc

 $Returns:		None.

 $Arguments:	View			- The current view
				status			- New status

*******************************************************************************/

void ATB_wap_status_change(T_WAP_VIEW *View, USHORT status)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_status_change");
#endif

	View->browser_status = status;

	/* Inform AUI of status change */
#if defined (FF_MMI_MMS) && defined (FF_GPF_TCPIP)
	//xrashmic 19 Aug, 2004 Bug: 2, 3, 36 and 42
	//The status information is handled by MMS module separatly.
	if(MMSactive)
	{
            //xrashmic 08 Feb, 2005 MMI-SPR-27853
            //Modified the parameters for this function.
		AUI_mms_status_notify(status);
	}
	else
	{
		AUI_wap_status_notify(View, status);
	}

#endif

#ifdef CO_UDP_IP
	AUI_wap_status_notify(View, status);
#endif

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_status_get

 $Description:	Return TRUE if the browser is in the supplied status.

 $Returns:		TRUE/FALSE

 $Arguments:	View			- The current view
				status			- Is the browser in this state?

*******************************************************************************/

BOOL ATB_wap_status_get(T_WAP_VIEW *View, USHORT status)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_status_get");
#endif

	if (View->browser_status==status)
		return (TRUE);
	else
		return (FALSE);
}


/*******************************************************************************

 $Function:    	ATB_uc_text_charsInWidth

 $Description:	Returns number of characters of the string that can fit into the given
 				width in pixels.

 $Returns:		Number of characters

 $Arguments:	str			- the string (unicode, converted)
				length		- the length of string to attempt to display
				width		- the width in pixels into which the string must fit

*******************************************************************************/

USHORT ATB_uc_text_charsInWidth(USHORT *str, USHORT length, SHORT width)
{
	USHORT strIndex;
	USHORT textwidth = 0;
	USHORT character;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_charsInWidth");
#endif

	for (strIndex = 0; strIndex<=length && textwidth<=width; strIndex++)
	{
		character = ((str[strIndex] & 0xFF)<<8) | ((str[strIndex] & 0xFF00)>>8);
		textwidth += font_getCharWidth(character);
	}

	return strIndex-1;
}


#ifdef FF_GPF_TCPIP
/*******************************************************************************

 $Function:    	ATB_uc_text_len

 $Description:	SPR#1816 - SH - Added
 				Returns length of unicode string

 $Returns:		Length of string

 $Arguments:	str		- the string

*******************************************************************************/

USHORT ATB_uc_text_len(USHORT *str)
{
	USHORT length;

#ifdef TRACE_ATBWAPAUI
	TRACE_EVENT("ATB_uc_text_len");
#endif

	length = 0;

	while (str[length]!=0)
	{
		length++;
	}

	return length;
}


#endif
/*******************************************************************************

 $Function:    	ATB_uc_text_copy

 $Description:	SPR#1816 - SH - Added
 				Copies unicode string src into dst

 $Returns:		Length of string copied

 $Arguments:	dst			- the destination string
 				src			- the source string
				destlen		- the maximum string length to copy

*******************************************************************************/

USHORT ATB_uc_text_copy(USHORT *dst, USHORT *src, USHORT destlen)
{
	USHORT length;

#ifdef TRACE_ATBWAPAUI
	TRACE_EVENT("ATB_uc_text_copy");
#endif

	length = 0;

	while (src[length]!=NULL && length<destlen)
	{
		dst[length] = src[length];
		length++;
	}

	dst[length] = NULL;	/* Add terminating NULL */

	return length;
}


/*******************************************************************************

 $Function:    	ATB_uc_text_width

 $Description:	Returns width of unicode string in pixels

 $Returns:		Width of string in pixels

 $Arguments:	str			- the string
				length		- the length of string to measure

*******************************************************************************/

USHORT ATB_uc_text_width(USHORT *str, USHORT length)
{
	USHORT width;
	USHORT index;
	USHORT character;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_uc_text_width");
#endif

	width = 0;

	for (index=0; str[index]!=0 && index<length; index++)
	{
		character = ((str[index] & 0xFF)<<8) | ((str[index] & 0xFF00)>>8);
		width += font_getCharWidth(character);
	}

	return width;
}

  // Apr 28 2005  REF:  MMI-SPR-30400 x0012849
  // Thos function is called to see that text is not displayed on the scroll bar space
/*******************************************************************************
 $Function:    	ATB_uc_text_cut

 $Description:	 To see that the displayed string wont appear on the scroll bar space.
                       This function is same as ATB_uc_text_crop but it wont put .. at the end.
 $Returns:		Length of the cropped string in unicode characters.

 $Arguments:	str			- the string (unicode, converted)
 				length		- the original length
				width		- the maximum pixel width of the new string

*******************************************************************************/

USHORT ATB_uc_text_cut(USHORT *str, USHORT length, SHORT width)
{
	USHORT maxlen = ATB_uc_text_charsInWidth(str, length, width);	/* Maximum length of string that will fit */

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_uc_text_cut");
#endif

	if (length>maxlen)
	{
		length = maxlen;
		str[length] = NULL;
	}
	return length;
}

/*******************************************************************************

 $Function:    	ATB_uc_text_crop

 $Description:	Crops a unicode string if necessary to fit the supplied pixel width

 $Returns:		Length of the cropped string in unicode characters.

 $Arguments:	str			- the string (unicode, converted)
 				length		- the original length
				width		- the maximum pixel width of the new string

*******************************************************************************/

USHORT ATB_uc_text_crop(USHORT *str, USHORT length, SHORT width)
{
	USHORT maxlen = ATB_uc_text_charsInWidth(str, length, width);	/* Maximum length of string that will fit */

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_crop_text");
#endif

	if (length>maxlen)
	{
		length = maxlen;
		str[length] = NULL;

		/* Add '..' to indicate text is cropped */

		if (length>0)
			str[length-1] = '.';
		if (length>1)
			str[length-2] = '.';
	}

	return length;
}


/*******************************************************************************

 $Function:    	ATB_uc_text_convert

 $Description:	Swap the upper and lower bytes of each unicode character in a string
 				(Converts standard unicode to MMI unicode)

 $Returns:		the string

 $Arguments:	str			- the source/destination string
				strlen		- the length of the string

*******************************************************************************/

USHORT* ATB_uc_text_convert (USHORT *str, USHORT strlen)
{
	USHORT length;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_uc_text_convert()");
#endif

	for (length = 0; str[length]!=0 && length < strlen; length++)
	{
		str[length] = ((str[length]&0xFF)<<8) | ((str[length]&0xFF00)>>8);
	}

	str[length] = NULL;	/* Add terminating NULL */

	return str;
}


/*******************************************************************************

 $Function:    	ATB_uc_to_char

 $Description:	Converts a MMI-converted unicode string to a char string

 $Returns:		The length in unicode characters of the destination string

 $Arguments:	dst			- the destination string
				src			- the source string
				srclen		- the length of the source string

*******************************************************************************/

USHORT ATB_uc_to_char(char *dst, USHORT *src, USHORT srclen)
{
	USHORT length;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_uc_to_char()");
#endif

	for (length = 0; length < srclen && src[length]!=0; length++)
	{
		dst[length] = (char)(src[length]>>8);
	}

	dst[length] = 0;	/* Add terminating NULL */

	return length;
}


/*******************************************************************************

 $Function:    	ATB_char_to_uc

 $Description:	Converts a char string to a MMI-converted unicode string

 $Returns:		The length in unicode characters of the destination string

 $Arguments:	dst			- the destination string
				src			- the source string

*******************************************************************************/

USHORT ATB_char_to_uc (USHORT *dst, char *src)
{
	USHORT length = 0;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_char_to_uc()");
#endif

	while (src[length]!=NULL)
	{
		dst[length] = (USHORT) (src[length]<<8);
		length++;
	}

	dst[length] = 0;	/* Add terminating NULL */

	return length;
}

/*******************************************************************************

 $Function:    	ATB_uc_text_copy

 $Description:	Compares unicode strings

 $Returns:		zero if strings match, non zero otherwise

 $Arguments:	dst			- the destination string
 				src			- the source string
				len			- Number of UCS2 characters to compare

				xreddymn Dec-10-2004 for MMI-SPR-26159
*******************************************************************************/

USHORT ATB_uc_text_compare(USHORT *dst, USHORT *src, USHORT len)
{
	S32 i=0;

	if((dst==NULL)||(src==NULL))
	{
		return(len);
	}
	while ((src[i]==dst[i]) && (len>0))
	{
		len--;
		i++;
	}

	return len;
}

/*******************************************************************************

 $Function:    	ATB_conv_str_to_IP

 $Description:	Converts a string IP address to a long type IP address

 $Returns:		None.

 $Arguments:	str			- the string
 				len			- the original length
				ip			- pointer to where the result will be placed

*******************************************************************************/

GLOBAL const void ATB_conv_str_to_IP(const char* str, USHORT len, ULONG* ip)
{
	char buf[16];
	char *p, *pLast;
	ULONG i, j, k, m;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_conv_str_to_IP");
#endif

	if (len >= 16)
	{
		*ip = 0;
		return;
	}

	memcpy (buf, str, len);
	buf[len] = '\0';

	p = buf;

	pLast = buf;
	k = 0;
	j = 0;
	m = 1;
	for (i=0; i<len; i++)
	{
		if (*p=='.')
		{
			*p = '\0';
			k |= (atoi(pLast) & 0xFF) * m;
			m*=0x100;
			j++;
			p++;
			pLast = p;
			if (j EQ 3)
				break;
		}
		else
			p++;
	}

	if (j NEQ 3 OR p EQ &buf[len])
	{
		*ip = 0;
		return;
	}

	k |= (atoi(pLast) & 0xFF) * m;

	*ip = k;

	return;
}

#ifdef FF_GPF_TCPIP
/*******************************************************************************

 $Function:    	ATB_wap_data_call_connect

 $Description:	Connect the specified view
 				SPR#2086 - SH - Added

 $Returns:		None

 $Arguments:	View - The current view

*******************************************************************************/

void ATB_wap_data_call_connect(T_WAP_VIEW *View)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_data_call_connect()");
#endif

	if (View)
	{
		connect(View->object_id);
	}

	return;
}
#endif

/*******************************************************************************
 $Function:    	ATB_data_call_connected

 $Description:	Confirms that a data call has been connected

 $Returns:		None.

 $Arguments:	View - The current view

*******************************************************************************/
#ifdef FF_GPF_TCPIP
void ATB_data_call_connected(T_WAP_VIEW *View)
{
T_MMI_WAP_CONNECT_CNF parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_data_call_connected");
#endif

	/* SPR#2086 - SH - Use Current_view rather than View_header */

	if (View != NULL)
	{
		parameter.object_id = View->object_id;
	 	parameter.channel = View->channel;
		parameter.success = TRUE;
		M_MMI_WAP_CONNECT_CNF(&parameter);
	}


	if (View->object_id==WAP_PUSH_VIEW)
	{
		ATB_wap_status_change(View, ATB_WAP_NO_STATUS);
	}


	return;
}

#else /* #ifdef FF_GPF_TCPIP */
void ATB_data_call_connected(void)
{
T_MMI_WAP_CONNECT_CNF parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_data_call_connected");
#endif

	if (View_header != NULL)
	{
		parameter.object_id = View_header->object_id;
	 	parameter.channel = View_header->channel;


		parameter.success = TRUE;
		M_MMI_WAP_CONNECT_CNF(&parameter);
	}

	return;
}

#endif /* ! #ifdef FF_GPF_TCPIP */

#ifdef FF_GPF_TCPIP
/*******************************************************************************

 $Function:    	ATB_wap_data_call_disconnected

 $Description:	Confirms that a data call has been disconnected
 				SPR#2086 - SH - Added

 $Returns:		None

 $Arguments:	View - The current view

*******************************************************************************/

void ATB_wap_data_call_disconnected(T_WAP_VIEW *View)
{
	T_MMI_WAP_CONNECT_CNF parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_data_call_disconnected()");
#endif

    //xmzhou_trace_string("ATB_wap_data_call_disconnected called");

	if (View != NULL)
	{
		parameter.object_id = View->object_id;
	 	parameter.channel = View->channel;
		parameter.success = FALSE;
		M_MMI_WAP_CONNECT_CNF(&parameter);
	}

	return;
}

#endif /* #ifdef FF_GPF_TCPIP */
/*******************************************************************************

 $Function:    	ATB_wap_start_done

 $Description:	Confirms that WAP_START has completed

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

void ATB_wap_start_done(void)
{
	AUI_wap_start_done();

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_new_view_done

 $Description:	Confirms that WAP_NEW_VIEW has completed
				Also ends configuration information to WAP browser.
				Only send parameters that will not be modified during this
				session.

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

#ifdef FF_GPF_TCPIP
void ATB_wap_new_view_done(void)
{
	T_WAP_VIEW *View = Current_view;

	/* Set max no. of history entries */
	ATB_wap_config_int(View, configHISTORY_SIZE, MAX_HISTORY);

	ATB_wap_config_int(View, configCACHE_SIZE, WAP_cache_size);

	/* Display Images */
	//ATB_wap_config_int(View, configDISPLAY_IMAGES, 1);

	/* Don't update images */
	//ATB_wap_config_int(View, configUPDATE_IMAGES, 0);

	/* Set default channel */
	ATB_wap_config_int(View, configDEFAULT_CHANNEL, View->channel);

	/* Set connection port */
	ATB_wap_conn_config_int(View, configCLIENT_PORT, 3);

	/* Set online status (FALSE = not always online) */
	//ATB_wap_conn_config_int(View, configONLINE, FALSE);


	/* SPR#2086 - SH */
	ATB_wap_config_int(View, configPPG_AUTHENTICATION_REQUIRED, 0);


	AUI_wap_new_view_done();

	return;
}

#else /* #ifdef FF_GPF_TCPIP */

void ATB_wap_new_view_done(void)
{
	T_WAP_VIEW *View = Current_view;

	/* Set max no. of history entries */
	ATB_wap_config_int(View, configHISTORY_SIZE, MAX_HISTORY);

	/* Display Images */
	ATB_wap_config_int(View, configDISPLAY_IMAGES, 1);

	/* Don't update images */
	ATB_wap_config_int(View, configUPDATE_IMAGES, 0);

	/* Set default channel */
	ATB_wap_config_int(View, configDEFAULT_CHANNEL, View->channel);

	/* Setup stack mode */
	ATB_wap_conn_config_int(View, configSTACKMODE, MODE_CO_WSP);

	/* Set connection port */
	ATB_wap_conn_config_int(View, configCLIENT_LOCAL_PORT, 3);

	/* Set online status (FALSE = not always online) */
	ATB_wap_conn_config_int(View, configONLINE, FALSE);

	AUI_wap_new_view_done();

	return;
}

#endif /* ! #ifdef FF_GPF_TCPIP */
/*******************************************************************************

 $Function:    	ATB_wap_close_view_done

 $Description:	Confirms that WAP_CLOSE_VIEW has completed

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

void ATB_wap_close_view_done(void)
{
	AUI_wap_close_view_done();

	return;
}

/*******************************************************************************

 $Function:    	ATB_wap_cache_prepare

 $Description:	Tell WAP Browser to prepare the cache for shutdown

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

void ATB_wap_cache_prepare(void)
{
	T_MMI_WAP_CACHE_PREPARE_IND parameter;

	M_MMI_WAP_CACHE_PREPARE_IND(&parameter);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_cache_prepare_done

 $Description:	Confirms that WAP_CACHE_PREPARE has completed

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

void ATB_wap_cache_prepare_done(void)
{
	AUI_wap_cache_prepare_done();

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_terminate_done

 $Description:	Confirms that WAP_TERMINATE has completed

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

void ATB_wap_terminate_done(void)
{
	AUI_wap_terminate_done();

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_disconnect

 $Description:	Informs WAP browser that a disconnection has occurred

 $Returns:		None.

 $Arguments:	View - the current View

*******************************************************************************/

void ATB_wap_disconnect(T_WAP_VIEW *View)
{
	T_MMI_WAP_DISCONNECT_IND parameter;

	TRACE_FUNCTION("ATB_wap_disconnect()");

	parameter.object_id = View->object_id;
	parameter.channel = View->channel;

	M_MMI_WAP_DISCONNECT_IND(&parameter);

	return;
}

#ifdef FF_GPF_TCPIP
/*******************************************************************************

 $Function:    	ATB_wap_content_get

 $Description:	Fetches content
 				SPR#2086 - SH - Added

 $Returns:		WAP_FAIL if invalid request
 				WAP_OK otherwise.

 $Arguments:	urlID - A distinct ID for this request.  Returned in ATB_wap_content().
 				Url - The URL of the content to download.
 				reload - If TRUE, any version of the requested content in the cache
 				will be ignored, and the content will be fetched from the network.
 				acceptHeader - Specifies if any Accept-Header fields will be sent with
 				the request.  Can be NULL.

*******************************************************************************/

T_WAP_RES ATB_wap_content_get(UBYTE urlID, char *Url, BOOL reload, char *acceptHeader)
{
	T_MMI_WAP_CONTENT_REQ parameter;

	TRACE_FUNCTION("ATB_wap_content_get()");

	if (!parameter.Url)
		return WAP_FAIL;

	parameter.Url = Url;
	parameter.url_length = strlen(Url);
	parameter.urlID = urlID;
	parameter.reload = reload;
	parameter.AcceptHeader = acceptHeader;
	if (acceptHeader!=NULL)
	{
		parameter.acceptHeader_length = strlen(acceptHeader);
	}
	else
	{
		parameter.acceptHeader_length = 0;
	}

	//xmzhou_trace_string("****M_MMI_WAP_CONTENT_REQ****");

	M_MMI_WAP_CONTENT_REQ(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_content

 $Description:	The requested content.
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	urlID - A distinct ID for this request, provided by ATB_wap_content_get().
				Data - The downloaded data.
				data_length - The length of the downloaded data in bytes.
				moreData - If TRUE, there is more data to come.
				(This is just an indicator; the request for further data is made by the
				function M_WAP_MMI_CONTENT_IND.
				ContentType - The type of the downloaded data.
				contentType_length - The length of the downloaded data type, in bytes.
				totalSize - If the data comes in more than one chunk, this will give
				the total size of the assembled chunks.  However, this information may
				not be provided by the WAP gateway.
				errorNo - Error code.  If this is nonzero, it is reported to the AUI in
				the function AUI_error_dialog().

*******************************************************************************/

void ATB_wap_content(UBYTE urlID,
	char *Data,
	ULONG data_length,
	BOOL moreData,
	char *ContentType,
	ULONG contentType_length,
	ULONG totalSize,
	SHORT errorNo)
{
	TRACE_FUNCTION("ATB_wap_content()");

	/* Check if an error has occurred */
	if (Data==NULL || errorNo>0)
	{
		AUI_error_dialog(Current_view, errorNo);
		return;
	}
	//xrashmic 19 Aug, 2004 Bug: 2, 3, 36 and 42
	//The download data should not be displayed for MMS module
	if(!MMSactive)
	{

	AUI_wap_content(
		urlID,
		Data,
		data_length,
		moreData,
		ContentType,
		contentType_length,
		totalSize);
	}
	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_content_cancel

 $Description:	Cancel receipt of content.
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	urlID - The ID of the download.

*******************************************************************************/

void ATB_wap_content_cancel(UBYTE urlID)
{
	T_MMI_WAP_CONTENT_CANCEL_IND parameter;

	TRACE_FUNCTION("ATB_wap_content_cancel()");

	parameter.urlID = urlID;
	M_MMI_WAP_CONTENT_CANCEL_IND(&parameter);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_content_post

 $Description:	Post content
 				SPR#2086 - SH - Added

 $Returns:		WAP_FAIL if invalid request
 				WAP_OK otherwise.

 $Arguments:	urlID - A distinct ID for this request.  Returned in ATB_wap_content().
 				Url - The URL of the content to download.
 				reload - If TRUE, any version of the requested content in the cache
 				  will be ignored, and the content will be fetched from the network.
 				acceptHeader - Specifies if any Accept-Header fields will be sent with
 				  the request (NULL terminated).  Can be NULL.
 				Data - The data to post.
 				data_length - The length of the data to post, in bytes.
 				moreData - TRUE if there are more chunks to be sent after this one.
 				contentType - May contain the content type of the data
 				  (NULL terminated string).
 				sendMode - one of WAP_SENDMODE_URL_ENCODED,
 				  WAP_SENDMODE_MULTIPART_FORMDATA, WAP_SENDMODE_BINARY
 				contentDisp - when sendMode is WAP_SENDMODE_MULTIPART_FORMDATA,
 				  contentDisp can be set to e.g. filename for the content.  Can be NULL.
 				totalSize - If moreData is TRUE, this may indicate the total size of
 				  the data to be sent.

*******************************************************************************/

T_WAP_RES ATB_wap_content_post(
	UBYTE urlID,
	char *Url,
	BOOL reload,
	char *acceptHeader,
	char *Data,
	ULONG data_length,
	BOOL moreData,
	char *ContentType,
	UBYTE sendMode,
	char *ContentDisp,
	ULONG totalSize)
{
	T_MMI_WAP_CONTENT_POST_REQ parameter;

	TRACE_FUNCTION("ATB_wap_content_post()");
       //xmzhou_trace_string("ATB_wap_content_post called!!!!");

	//if (!parameter.Url || !parameter.Data)
	//	return WAP_FAIL;

	parameter.Url = Url;
	parameter.url_length = strlen(Url);
	parameter.urlID = urlID;
	parameter.reload = reload;
	parameter.AcceptHeader = acceptHeader;
	if (acceptHeader!=NULL)
	{
		parameter.acceptHeader_length = strlen(acceptHeader);
	}
	else
	{
		parameter.acceptHeader_length = 0;
	}
	parameter.Data = Data;
	parameter.data_length = data_length;
	parameter.moreData = moreData;
	parameter.ContentType = ContentType;
	if (ContentType!=NULL)
	{
		parameter.contentType_length = strlen(ContentType);
	}
	else
	{
		parameter.contentType_length = 0;
	}
	parameter.sendMode = sendMode;
	parameter.ContentDisp = ContentDisp;
	if (ContentDisp!=NULL)
	{
		parameter.contentDisp_length = strlen(ContentDisp);
	}
	else
	{
		parameter.contentDisp_length = 0;
	}
	parameter.totalSize = totalSize;
	//xmzhou_trace_string("ATB_wap_content_post call M_MMI_WAP_CONTENT_POST_REQ!!!!");
	M_MMI_WAP_CONTENT_POST_REQ(&parameter);

	return WAP_OK;
}


/*******************************************************************************

 $Function:    	ATB_wap_content_post_more

 $Description:	Post more content (after the first chunk has been sent)
 				SPR#2086 - SH - Added

 $Returns:		WAP_FAIL if invalid request
 				WAP_OK otherwise.

 $Arguments:	urlID - A distinct ID for this request, sent in ATB_wap_content_post().
 				Data - The data to post.
 				data_length - The length of the data to post, in bytes.
 				moreData - TRUE if there are more chunks to be sent after this one.

*******************************************************************************/

T_WAP_RES ATB_wap_content_post_more(
	UBYTE urlID,
	char *Data,
	ULONG data_length,
	BOOL moreData)
{
	T_MMI_WAP_CONTENT_POST_MORE_REQ parameter;

	TRACE_FUNCTION("ATB_wap_content_post_more()");
    //xmzhou_trace_string("ATB_wap_content_post_more called");

	//if (!parameter.Data)
	//	return WAP_FAIL;

	parameter.urlID = urlID;
	parameter.Data = Data;
	parameter.data_length = data_length;
	parameter.moreData = moreData;

	M_MMI_WAP_CONTENT_POST_MORE_REQ(&parameter);

	return WAP_OK;

}



/*******************************************************************************

 $Function:    	ATB_wap_push_load_SI

 $Description:	Load the requested service indication.
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	View - The current view
 				id - The identifier of the SI.

*******************************************************************************/

void ATB_wap_push_load_SI(T_WAP_VIEW *View, SHORT id)
{
	T_MMI_WAP_PUSH_LOAD_SI_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_load_SI()");
#endif

	parameter.object_id = View->object_id;
	parameter.id = id;

	M_MMI_WAP_PUSH_LOAD_SI_IND(&parameter);

	return;
}

/*******************************************************************************

 $Function:    	ATB_wap_push_delete_SI

 $Description:	Delete the requested service indication.
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	id - The identifier of the SI to delete.
 				selection - Parameter specifying which SI to delete (used if id is -1).
 				  Can be WAP_PUSH_DEL_ALL, WAP_PUSH_DEL_EXP,
 				  WAP_PUSH_DEL_NON_EXP, WAP_PUSH_DEL_LOADED,
 				  WAP_PUSH_DEL_NON_LOADED

*******************************************************************************/

void ATB_wap_push_delete_SI(SHORT id, UBYTE selection)
{
	T_MMI_WAP_PUSH_DELETE_SI_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_delete_SI()");
#endif

	parameter.id = id;
	parameter.selection = selection;

	M_MMI_WAP_PUSH_DELETE_SI_IND(&parameter);

	return;
}

/*******************************************************************************

 $Function:    	ATB_wap_push_get_SI_info

 $Description:	Request info on the specified SI.
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	id - The identifier of the SI to delete.
 				selection - Parameter specifying for which SI to get info (used if id is -1).
 				  Can be WAP_PUSH_SHOW_ALL, WAP_PUSH_SHOW_EXP,
 				  WAP_PUSH_SHOW_NON_EXP, WAP_PUSH_SHOW_LOADED,
 				  WAP_PUSH_SHOW_NON_LOADED

*******************************************************************************/

void ATB_wap_push_get_SI_info(SHORT id, UBYTE selection)
{
	T_MMI_WAP_PUSH_GET_SI_INFO_REQ parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_get_SI_info()");
#endif

	parameter.id = id;
	parameter.selection = selection;

	M_MMI_WAP_PUSH_GET_SI_INFO_REQ(&parameter);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_push_save_repository

 $Description:	Save the push repository to flash
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	None

*******************************************************************************/

void ATB_wap_push_save_to_flash(void)
{
	T_MMI_WAP_PUSH_SAVE_TO_FLASH_IND parameter;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_load_SI()");
#endif

	M_MMI_WAP_PUSH_SAVE_TO_FLASH_IND(&parameter);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_push_SI_new

 $Description:	A new SI has been received
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	id - identifier for the SI
				created - Date and time of when SI was created in UTC format
				expires - Date and time of when SI expires in UTC format
				Message - The description of the received SI, to be presented to the
				  end-user
				message_length - Length of Message in Unicode characters
				expired - TRUE if SI has expired, FALSE otherwise
				Url - The URL of the service to retrieve, or NULL if not provided
				url_length - Length of Url in characters
				priority - Priority of SI.  Can be: WAP_PUSH_LOW_PRIO,
				  WAP_PUSH_HIGH_PRIO, WAP_PUSH_CACHE_PRIO.
				InitURL - Identifies the push initiator.  NULL if not provided
				initURL_length - Length of InitURL in characters
				applicationType - Allows application to map message to right user
				  agent.  Can be WAP_APPLICATION_WML, WAP_APPLICATON_WTA.
				newChannelId - For Bluetooth support

*******************************************************************************/

void ATB_wap_push_SI_new(
	SHORT id,
	ULONG created,
	ULONG expires,
	USHORT *Message,
	ULONG message_length,
	BOOL expired,
	char *Url,
	ULONG url_length,
	UBYTE priority,
	char *InitURL,
	ULONG initURL_length,
	UBYTE applicationType,
	UBYTE newChannelId
	)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_SI_new()");
#endif

	/* Save the current push repository to flash */

	ATB_wap_push_save_to_flash();

	/* Indicate to the user that a new push message has arrived
	 * (only if the appropriate setting is set to TRUE) */

	if (ATB_wap_profile_setting(WAP_STATUS_PUSHMESSAGES))
	{
		AUI_wap_push_show(
			Message,
			(USHORT)message_length,
			id,
			(char *)Url,
			(USHORT)url_length);
	}

	return;
}

/*******************************************************************************

 $Function:    	ATB_wap_push_SL_new

 $Description:	A new SL has been received

 $Returns:		void

 $Arguments:	id - identifier for the SL
				Url - The URL of the service to retrieve, or NULL if not provided
				url_length - Length of Url in characters
				priority - Priority of SL.  Can be: WAP_PUSH_LOW_PRIO,
				  WAP_PUSH_HIGH_PRIO, WAP_PUSH_CACHE_PRIO.
				InitURL - Identifies the push initiator.  NULL if not provided
				initURL_length - Length of InitURL in characters
				applicationType - Allows application to map message to right user
				  agent.  Can be WAP_APPLICATION_WML, WAP_APPLICATON_WTA.
				newChannelId - For Bluetooth support

				xreddymn Mar-16-2005 MMI-SPR-29767

*******************************************************************************/

void ATB_wap_push_SL_new(
	SHORT id,
	char *Url,
	ULONG url_length,
	UBYTE priority,
	char *InitURL,
	ULONG initURL_length,
	UBYTE applicationType,
	UBYTE newChannelId
	)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_SL_new()");
#endif

	// Save the current push repository to flash

	ATB_wap_push_save_to_flash();

	// Launch WAP with the URL received in the SL message
	
	AUI_wap_push_load_SL(id, Url, url_length);

	return;
}

/*******************************************************************************

 $Function:    	ATB_wap_push_SI_info

 $Description:	Returns info about the specified SI.
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	id - identifier for the SI
				status - Status of the SI.  Can be WAP_PUSH_STATUS_NON_LOADED,
				  WAP_PUSH_STATUS_LOADED.
				created - Date and time of when SI was created in UTC format
				expires - Date and time of when SI expires in UTC format
				Message - The description of the received SI, to be presented to the
				  end-user
				message_length - Length of Message in Unicode characters
				expired - TRUE if SI has expired, FALSE otherwise
				Url - The URL of the service to retrieve, or NULL if not provided
				url_length - Length of Url in characters
				priority - Priority of SI.  Can be: WAP_PUSH_LOW_PRIO,
				  WAP_PUSH_HIGH_PRIO, WAP_PUSH_CACHE_PRIO.
				InitURL - Identifies the push initiator.  NULL if not provided
				initURL_length - Length of InitURL in characters

*******************************************************************************/

void ATB_wap_push_SI_info(
	SHORT id,
	UBYTE status,
	ULONG created,
	ULONG expires,
	USHORT *Message,
	ULONG message_length,
	BOOL expired,
	char *Url,
	ULONG url_length,
	UBYTE priority,
	char *InitURL,
	ULONG initURL_length
	)
{
#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_SI_info()");
#endif

	AUI_wap_push_info(
		Message,
		message_length,
		id,
		(char *)Url,
		(USHORT)url_length,
		status,
		created,
		expired,
		priority);
}

char WAPServiceCentre[30] = {0};
T_MFW_PHB_TON addr_type;
T_MFW_PHB_TON sc_type;

/*******************************************************************************

 $Function:    	ATB_wap_push_SMS_received

 $Description:	Notifies WAP that a WAP SMS has been received
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	smsc - The service centre address (NULL terminated)
 				tosca - Service centre T.O.N.
 				number - The address of the sender
 				toa - Sender addresss T.O.N.
 				Data - data of message
 				data_length - Length of the message in bytes

*******************************************************************************/

void ATB_wap_push_SMS_received(
	char *Smsc,
	UBYTE tosca,
	char *number,
	UBYTE toa,
	char *Udh,
	ULONG udh_length,
	char *Data,
	ULONG data_length)
{
	T_MMI_WAP_PUSH_SMS_RECEIVED_IND parameter;
	USHORT totalsize;
	char *sms_data;

#ifdef TRACE_ATBWAPAUI
	TRACE_FUNCTION("ATB_wap_push_SMS_received");
	TRACE_EVENT_P2("udh_length %d, data_length: %d", udh_length, data_length);
#endif

	/* Concatenate the UDH and data */

	totalsize = udh_length+data_length+1;
	sms_data = (char *)AUI_wap_memory_alloc(totalsize);

	sms_data[0] = udh_length;
	memcpy((void *)&sms_data[1], Udh, udh_length);
	memcpy((void *)&sms_data[udh_length+1], Data, data_length);

	/* Store WAP Service Centre */

	memset((void *)WAPServiceCentre, 0, sizeof(WAPServiceCentre));

	if (Smsc)
	{
		strcpy(WAPServiceCentre, Smsc);
		TRACE_EVENT_P1("smsc: %s", WAPServiceCentre);
	}

	addr_type = toa;
	sc_type = tosca;

	parameter.Source = number;
	parameter.source_length = (ULONG)strlen(number);
	parameter.Data = sms_data;
	parameter.data_length = (ULONG)totalsize;

	M_MMI_WAP_PUSH_SMS_RECEIVED_IND(&parameter);

	AUI_wap_memory_free((void *)sms_data, totalsize);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_push_SMS_send

 $Description:	WAP requests MMI to send an SMS
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	Smsc - The service centre address
 				smsc_length - Length of the service centre in characters
 				Destination - The address of the destination
 				destination_length - The length of the destination
 				toa - Sender addresss T.O.N.
 				Data - data of message
 				data_length - Length of the message in bytes

*******************************************************************************/

void ATB_wap_push_SMS_send(
	char *Smsc,
	ULONG smsc_length,
	char *Destination,
	ULONG destination_length,
	char *Data,
	ULONG data_length)
{
	char *Destination_ascii;
	char dummy[] = "Test";
#ifdef TRACE_AUIWAP
	TRACE_FUNCTION("ATB_wap_push_SMS_send");
#endif

	/* Ensure address is null-terminated */

	Destination_ascii = (char *)AUI_wap_memory_alloc(destination_length+1);
	memcpy((void *)Destination_ascii, (void *)Destination, destination_length);
	Destination_ascii[destination_length] = 0;

	sms_submit_wap_sms(MFW_SMS_REPLY,
	(CHAR *)Destination_ascii,
	addr_type,
	(UBYTE *)Data,
	(USHORT)data_length,
	WAPServiceCentre,
	sc_type);

	AUI_wap_memory_free((void *)Destination_ascii,destination_length+1);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_push_SMS_sent

 $Description:	Notifies WAP that a WAP SMS has been sent
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	None

*******************************************************************************/

void ATB_wap_push_SMS_sent(void)
{
	T_MMI_WAP_PUSH_SMS_SENT_IND parameter;

#ifdef TRACE_AUIWAP
	TRACE_FUNCTION("ATB_wap_push_SMS_sent");

#endif

	parameter.dummy = 0;

	M_MMI_WAP_PUSH_SMS_SENT_IND(&parameter);

	return;
}


/*******************************************************************************

 $Function:    	ATB_wap_push_SMS_error

 $Description:	Notifies WAP that a WAP SMS has not been sent
 				SPR#2086 - SH - Added

 $Returns:		None.

 $Arguments:	error - an ID for the error

*******************************************************************************/

void ATB_wap_push_SMS_error(UBYTE error)
{
	T_MMI_WAP_PUSH_SMS_ERROR_IND parameter;

#ifdef TRACE_AUIWAP
	TRACE_FUNCTION("ATB_wap_push_SMS_error");
	TRACE_EVENT_P1("**ERROR: %d**",error);
#endif

	parameter.message = error;

	M_MMI_WAP_PUSH_SMS_ERROR_IND(&parameter);

	return;
}

#endif /* #ifdef FF_GPF_TCPIP */


/*******************************************************************************

 $Function:    	long_IP_to_char_IP

 $Description:	Converts a ULONG IP address into an IP address string suitable for an
 				editor.

 $Returns:		None.

 $Arguments:	IPs - The IP address
 				IPd - The string in which to store the result

*******************************************************************************/

void long_IP_to_char_IP(ULONG IPs,char* IPd)
{
	ULONG tempLong;
	char tempChar;
	int i;
	char temp[50];

#ifdef TRACE_ATBWAPAUI
	sprintf(temp,"IP Address %X",(int)IPs);
	TRACE_EVENT(temp);
#endif

	for (i=3;i>=0;i--)
	{
		tempLong=((IPs)>>8*i)&(0xFF);
		*IPd = (char)tempLong;
#ifdef TRACE_ATBWAPAUI
		sprintf(temp,"IP %d %X",i,(int)*IPd);
		TRACE_EVENT(temp);
#endif
		IPd++;
	}


}


/*******************************************************************************

 $Function:    	rAT_WAP_PPP_connected

 $Description:	Indication from ACI that PPP is connected

 $Returns:		None.

 $Arguments:	cId - Id of the WAP call
 				IPAddress - Dynamically assigned IP address

*******************************************************************************/
#ifdef FF_GPF_TCPIP
//TISHMMS Project
extern void M4_DebugStringMessage(char *in_string, UINT8 ucNumber,unsigned long para);

void rAT_WAP_PPP_connected(SHORT cId,ULONG IPAddress)
{
	char charIP[5];

	TRACE_FUNCTION("rAT_WAP_PPP_connected");

	/* SPR#1569 - SH - If there are no open views, disconnect and exit */

	if (!View_header)
	{
		TRACE_EVENT("** WAP has closed, disconnecting call **");
		/* SPR#1575 - SH - Call this function to end a GPRS or CSD call */
		AUI_end_call(0);	/* SPR#1850 - SH - Call ID 0, disconnect any call */
		return;
	}

	/* SPR#1189 - SH - If the browser is not in the correct state, disconnect */

	if (ATB_wap_status_get(Current_view, ATB_WAP_ONLINE_CONNECTION_CLOSED))
	{
		TRACE_EVENT("** WAP is not in correct status, disconnecting call **");
		AUI_end_call(0);
		return;
	}

	/* Send new IP address as config information */

	if (IPAddress)
	{
		charIP[4]='\0';

		long_IP_to_char_IP(IPAddress,(char*)charIP);

		/* Set IP address host */
		ATB_wap_conn_config_str(Current_view, WAP_transCharIP, charIP, 4);
	}

	/* SPR#1574 - SH - Removed parameter */

	ATB_wap_status_change(Current_view,ATB_WAP_CONNECTING);

	ATB_data_call_connected(Current_view);
	return;
}

#else /* #ifdef FF_GPF_TCPIP */

void rAT_WAP_PPP_connected(SHORT cId,ULONG IPAddress)
{
	char charIP[5];

	TRACE_FUNCTION("rAT_WAP_PPP_connected");

	/* If there are no open views, disconnect and exit */

	if (!View_header)
	{
		TRACE_EVENT("** WAP has closed, disconnecting call **");
		AUI_wap_end_call(0);	/* Call ID 0, disconnect any call */
		return;
	}

	/* If the browser is not in the correct state, disconnect */

	if (ATB_wap_status_get(Current_view, ATB_WAP_ONLINE_CONNECTION_CLOSED))
	{
		TRACE_EVENT("** WAP is not in correct status, disconnecting call **");
		AUI_wap_end_call(0);
		return;
	}

	/* Send new IP address as config information */

	if (IPAddress)
	{
		charIP[4]='\0';

		long_IP_to_char_IP(IPAddress,(char*)charIP);

		/* Set IP address host */
		ATB_wap_conn_config_str(Current_view, configUDP_IP_SRC, charIP, 4);
	}

	/* Set new MMI status */

	ATB_wap_status_change(Current_view,ATB_WAP_CONNECTING);

	/* Send connection confirmation to WAP Browser */

	ATB_data_call_connected();

	return;
}

#endif /* ! #ifdef FF_GPF_TCPIP */

/*******************************************************************************

 $Function:    	rAT_WAP_start_login

 $Description:	Login has begun for CSD

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

void rAT_WAP_start_login(void)
{
	UBYTE temp;

	TRACE_FUNCTION("rAT_WAP_start_login");

	temp = dspl_Enable(0);

	/* SPR#1569 - SH - Only change status if current view exists */

	if (Current_view)
	{
		/* SPR#1574 - SH - Removed parameter */
		ATB_wap_status_change(Current_view, ATB_WAP_LOGGING_IN);
	}

	dspl_Enable(temp);

	return;
}


/*******************************************************************************

 $Function:    	rAT_WAP_start_gprs_login

 $Description:	Login has started over GPRS

 $Returns:		None.

 $Arguments:	None.

*******************************************************************************/

//NM take it out #ifdef MMI_WAP_ENABLED

void rAT_WAP_start_gprs_login(void)
{
	UBYTE temp;

	TRACE_FUNCTION("rAT_WAP_start_gprs_login");

	temp = dspl_Enable(0);

	/* SPR#1569 - SH - Only change status if current view exists */

	if (View_header && Current_view)
	{
		/* SPR#1982 - SH - Only change status if we are ATTACHING */
		if (ATB_wap_status_get(Current_view, ATB_WAP_ATTACHING))
		{
			ATB_wap_status_change(Current_view, ATB_WAP_CONNECTING);
		}
	}

	dspl_Enable(temp);

	return;
}

//NM #endif

/*******************************************************************************

 $Function:    	rAT_WAP_call_disconnected

 $Description:	Callback - disconnection occurred

 $Returns:		None.

 $Arguments:	cId - ID of the WAP call

*******************************************************************************/

#ifdef FF_GPF_TCPIP
void rAT_WAP_call_disconnected(SHORT cId)
{
	UBYTE temp;
	T_MMI_WAP_CONNECT_CNF parameter;

	TRACE_FUNCTION("rAT_WAP_call_disconnected");

	temp = dspl_Enable(0);

	/* SPR#1569 - SH - If there are no open views, do nothing */


	if (Current_view)
	{
		/* SPR#1574 - SH - Removed parameter */
		ATB_wap_status_change(Current_view, ATB_WAP_ONLINE_CONNECTION_CLOSED);

		parameter.object_id = Current_view->object_id;
	 	parameter.channel = Current_view->channel;
		parameter.success = FALSE;
		M_MMI_WAP_CONNECT_CNF(&parameter);
	}

	dspl_Enable(temp);

	return;
}

#else /* #ifdef FF_GPF_TCPIP */

void rAT_WAP_call_disconnected(SHORT cId)
{
	UBYTE temp;
	T_MMI_WAP_CONNECT_CNF parameter;

	TRACE_FUNCTION("rAT_WAP_call_disconnected");

	temp = dspl_Enable(0);

	/* If there are no open views, do nothing */

	if (View_header != NULL)
	{
		/* Inform MMI of connection closed */

		if (Current_view)
		{
			ATB_wap_status_change(Current_view, ATB_WAP_ONLINE_CONNECTION_CLOSED);
		}

		/* Inform WAP Broswer of connection closed */

		parameter.object_id = View_header->object_id;
	 	parameter.channel = View_header->channel;
		parameter.success = FALSE;
		M_MMI_WAP_CONNECT_CNF(&parameter);
		Current_view = View_header;
	}

	dspl_Enable(temp);

	return;
}

#endif /* ! #ifdef FF_GPF_TCPIP */
/*******************************************************************************

 $Function:    	writeerrorFFS/writeflagFFS

 $Description:	These functions are provided for debugging purposes

 $Returns:		None.

 $Arguments:

*******************************************************************************/

void writeerrorFFS(short error)
{
	UBYTE errordigits[6];
	sprintf((char *)errordigits, "%d", error);
	ffs_file_write("/mmi/errormmi",  &errordigits, sizeof(errordigits), FFS_O_TRUNC | FFS_O_CREATE);
}

void writeflagFFS(UBYTE flag)
{
	ffs_file_write("/mmi/flag",  &flag, sizeof(flag), FFS_O_TRUNC | FFS_O_CREATE);
}