/*
+-------------------------------------------------------------------+
| PROJECT: MMI-Framework (8445)		$Workfile:: mmiBluetooth.c			$|
| $Author:: NDH						$Revision::  1						$|
| CREATED: 26.04.04					$Modtime:: 26.04.04 10:21			$|
| STATE  : code														 |
+-------------------------------------------------------------------+


   MODULE  : MFW_BT

   PURPOSE : This module contains the functions for MFW Bluetooth Management


*/

#define ENTITY_MFW

#include <string.h>

#if defined (NEW_FRAME)

#include "typedefs.h"
#include "vsi.h"
#include "pei.h"
#include "custom.h"
#include "gsm.h"
#include "prim.h"

#else

#include "STDDEFS.H"
#include "custom.h"
#include "gsm.h"
#include "vsi.h"

#endif

#include "message.h" /* included for aci_cmh.h .... */
//#include "prim.h" /* included for aci_cmh.h .... */
#include "aci_cmh.h" /* included for mfw_sat.h, included for MmiDummy.h, included for MmiMenu.h */

#include "mfw_mfw.h"
#include "mfw_win.h"
#include "mfw_icn.h"	/* included for mfw_mnu.h */
#include "mfw_mnu.h"
#include "mfw_tim.h"
#include "mfw_kbd.h"
#include "mfw_sat.h" /* included for MmiDummy.h, included for MmiMenu.h */

#include "mfw_bte.h"
#include "mfw_bt_dm.h"
#include "mfw_bt_dg.h"
#include "mfw_bt_ag.h"
#include "mfw_bt_op.h"
#include "mfw_bt_ft.h"
#include "mfw_bt_geh.h"
//#include "mfw_bt_temp.h"

#include "MmiBlkLangDB.h"
#include "mmiColours.h"
#include "MmiDialogs.h"
#include "mmiBluetooth.h"

#include "MmiDummy.h" /* included for MmiMenu.h */
#include "MmiLists.h"
#include "MmiMenu.h"

#include "MmiSoftKeys.h"

#include "AUIEditor.h"

/*
** Local Typedefs
*/
typedef struct{
	MfwHnd			bt_win;
	MfwHnd			bt_dev_name_win;
	MfwHnd			bt_pin_req_win;
	MfwHnd			bt_authorize_win;
	MfwHnd			bt_discoverable_timer;
	MfwHnd			bt_connection_timer;
	
	BOOL			bt_isEnabled;
	BOOL			bt_isActive;
	BOOL			bt_stopBtOnDiscoverableTimeout;
	BOOL			bt_DevNameForStartup;
	UBYTE			bt_num_active_connections;
}	T_MMI_BtData;


typedef struct{
	T_MMI_CONTROL	mmi_control;

	MfwHnd			win;
	MfwHnd			bt_auth_info_win;
	MfwHnd			bt_auth_info_editor;
	MfwHnd			bt_auth_menu;

	T_MFW_BT_DM_AUTHORIZE_REQ	*bt_auth_req_param;
	UBYTE						*bt_auth_info_text;
	USHORT						bt_auth_info_text_size;
	
}	T_MMI_BT_Authorise_Data;


typedef struct{
	T_MMI_CONTROL	mmi_control;

	MfwHnd			win;
	MfwHnd			bt_dev_name_editor;
	UBYTE			bt_device_name[MFW_BT_NAME_LENGTH+1];
	T_MFW_BT_DM_DEV_ADDR	bt_dev_address;			/* CQ21843 - Bt Addr of remote device */
	T_MFW_BT_REM_DEVICE_INFO *rem_device_info;		/* CQ21843 - Global information about the remote device*/
}	T_MMI_BT_Dev_Name_Data;


typedef struct{
	T_MMI_CONTROL	mmi_control;

	MfwHnd			win;
	MfwHnd			bt_pin_req_editor;
	MfwHnd			bt_please_wait_dialog;
	
	T_MFW_BT_DM_DEV_ADDR	bt_pin_req_dev;
	UBYTE			bt_pin_req_buf[MFW_BT_MAX_PIN_CODE_LEN+1];

	T_BT_REQ_RESP	bt_required_response;
}	T_MMI_BT_PIN_Req_Data;

#if 0
typedef struct {
	T_MFW_BT_DM_DEV_ADDR	bd_addr;
	UBYTE					bd_name[MFW_BT_NAME_LENGTH + 1];
	T_MFW_BT_SERVICE_MASK	services;
	BOOL					isPaired;
	BOOL					isKnown;
	BOOL					isTrustued;
	T_MFW_BT_SERVICE_MASK	trustedServices;
} T_MMI_BtDevDetails;
#endif

typedef struct{
	T_MMI_CONTROL				srch_bt_control;

	MfwHnd						win;
	MfwHnd						srch_bt_cmpnt;
	MfwHnd						srch_bt_pairing_pin_editor;
	MfwHnd						srch_bt_please_wait_dialog;
	MfwHnd						srch_bt_dev_list_win;
	MfwHnd						srch_bt_show_services_win;
	MfwHnd						srch_bt_search_timer;
	
	T_BT_SEARCH_MODE			srch_bt_mode;

	UBYTE						bt_pairing_pin_buf[MFW_BT_MAX_PIN_CODE_LEN+1];

	T_BT_REQ_RESP				srch_bt_req_resp;

	ListMenuData    				srch_bt_list_devices_menu_data;
	ListMenuData    				srch_bt_show_services_menu_data;
	UBYTE						srch_bt_num_devices;
	UBYTE						srch_bt_device_count;
	ListCbFunc					srch_bt_dev_list_cb;
	T_MFW_BT_REM_DEVICE_INFO	*srch_bt_dev_list;
	UBYTE						srch_bt_cur_dev_idx;
	ULONG						srch_bt_cur_dev_serv_list[BTA_MAX_SERVICE_ID-1];
}	T_MMI_BtSearchData;

typedef struct
{
  T_MMI_CONTROL   mmi_control;
  T_MFW_HND       win;
  T_MFW_HND       kbd;
  T_MFW_HND       kbd_long;
  T_MFW_HND       menu;
  T_VOID_FUNC     func_cb;
  T_VOID_FUNC	cancel_cb;
  /*
   * internal data
   */
}T_bt_menu;

/*
** Local Defines
*/
#define BT_MAX_DISPLAY_DEV_NAME_LENGTH	20

#define BT_INFO_SCRN_TIMEOUT		1500
#define BT_SEARCH_RESP_TIMEOUT       15000		/* 15 seconds */
#define BT_AUTHORISE_RESP_TIMEOUT 30000		/* 30 seconds */
#define BT_DISCOVERABLE_DURATION	180000		/* 3 minutes */
#define BT_CONNECTION_DURATION	60000		/* 1 minute */

/*
** Local Function Prototypes
*/
static int  mmi_bluetooth_device_mnu_cb(MfwMnu * mnu, MfwMnuItem * item);
static void mmi_bluetooth_editor_cb(T_MFW_HND win, USHORT identifier, SHORT reason);
static int mmi_bluetooth_search_cb(T_MFW_EVENT evnt, void* para);
static int mmi_bluetooth_root_cb(T_MFW_EVENT evnt, void* para);
static int mmi_bluetooth_search_timer_cb(MfwEvt e, MfwTim *t);
static int mmi_bluetooth_discovery_timer_cb(MfwEvt e, MfwTim *t);
static int mmi_bluetooth_connection_timer_cb(MfwEvt e, MfwTim *t);
static void mmi_bluetooth_dlg_cb(void);
static void mmi_bt_srch_no_device_found_dlg_cb(void);
static MfwHnd mmi_bluetooth_show_please_wait(T_MFW_HND parent);
static MfwHnd mmi_bluetooth_show_info_callback(T_MFW_HND parent, int str1, int str2, T_VOID_FUNC callback);
static MfwHnd mmi_bluetooth_show_info(T_MFW_HND parent, int str1, int str2);

T_MFW_HND bt_menu_start(MfwHnd parent,MfwMnuAttr* menuAttr,T_VOID_FUNC func_cb);
static T_MFW_HND bt_menu_create(MfwHnd parent);
static void bt_menu_destroy(MfwHnd window);
static void bt_menu (T_MFW_HND win, USHORT event, SHORT value, void * parameter);
static int bt_menu_mnu_cb (MfwEvt e, MfwMnu *m);
static int bt_menu_win_cb (MfwEvt e, MfwWin *w);
static int bt_menu_kbd_cb (MfwEvt e, MfwKbd *k);
static int bt_menu_kbd_long_cb (MfwEvt e, MfwKbd *k);
static void mmi_bt_authorize_editor_cb(T_MFW_HND win, USHORT identifier, SHORT reason);
static int mmi_bt_authorize_display_info(MfwMnu* m, MfwMnuItem* i);
static int mmi_bt_authorize_once(MfwMnu* m, MfwMnuItem* i);
static int mmi_bt_authorize_always(MfwMnu* m, MfwMnuItem* i);
static int mmi_bt_dont_authorize(MfwMnu* m, MfwMnuItem* i);
static void mmi_bt_authorize_rsk(void);
static int bt_srch_dev_pair (MfwMnu * mnu, MfwMnuItem * item);
static int bt_srch_dev_show_services (MfwMnu * mnu, MfwMnuItem * item);
static int bt_srch_dev_set_name (MfwMnu * mnu, MfwMnuItem * item);		/* CQ21843 - Menu Action Function to set Friendly name for Remote device */
static int bt_srch_dev_add_known (MfwMnu * mnu, MfwMnuItem * item);
static int bt_srch_dev_rem_known (MfwMnu * mnu, MfwMnuItem * item);
static void bt_srch_dev_list_searching_cb(T_MFW_HND Parent, ListMenuData *ListData);
static void bt_srch_dev_list_listmnu_cb(T_MFW_HND Parent, ListMenuData * ListData);
static void bt_srch_service_list_listmnu_cb(T_MFW_HND Parent, ListMenuData * ListData);
static int bt_count_dev_services(T_MFW_BT_SERVICE_MASK services, T_MFW_BT_SERVICE_MASK *srv_mask_arry);
static int bt_get_TxtId_for_service(T_MFW_BT_SERVICE_MASK service);

/*
** Local Static Data
*/
static  MfwMnuItem menuBtAuthorizeItems[] =
{
	{0,0,0, (char*) TxtBtInfo,  		0, (MenuFunc)mmi_bt_authorize_display_info,	item_flag_none},
	{0,0,0, (char*) TxtBtYesOnce,	0, (MenuFunc)mmi_bt_authorize_once,			item_flag_none},
	{0,0,0, (char*) TxtBtYesAlways,	0, (MenuFunc)mmi_bt_authorize_always,			item_flag_none},
	{0,0,0, (char*) TxtNo,			0, (MenuFunc)mmi_bt_dont_authorize,			item_flag_none }
};

static const MfwMnuAttr menuBtAuthorize =
{
	&menuArea,
	MNU_LEFT | MNU_LIST | MNU_CUR_LINE,					/* centered page menu       */
	-1,													/* use default font         */
	(MfwMnuItem*)menuBtAuthorizeItems,				/* with these items         */
	sizeof(menuBtAuthorizeItems)/sizeof(MfwMnuItem),	/* number of items          */
	COLOUR_LIST_XX,										/* Colour */
	TxtBtAuthorize,										/* Hdr Id */
	NULL,												/* Background */
	MNUATTRSPARE										/* unused */
};


static MfwMnuAttr menuBtSearchListAttr =
{
	&menuArea,
	MNU_LEFT | MNU_LIST | MNU_CUR_LINE,		/* centered page menu       */
	-1,										/* use default font         */
	NULL,									/* with these items (filled in later)  */
	0,										/* number of items (filled in leter)  */
	COLOUR_LIST_XX,							/* Colour */
	TxtNull,									/* Hdr Id */
	NULL,									/* Background */
	MNUATTRSPARE							/* unused */
};


static MfwMnuAttr menuBtShowServicesListAttr =
{
	&menuArea,
	MNU_LEFT | MNU_LIST | MNU_CUR_LINE,		/* centered page menu       */
	-1,										/* use default font         */
	NULL,									/* with these items (filled in later)  */
	0,										/* number of items (filled in leter)  */
	COLOUR_LIST_XX,							/* Colour */
	TxtNull,									/* Hdr Id */
	NULL,									/* Background */
	MNUATTRSPARE							/* unused */
};

static  MfwMnuItem menuBtDeviceOptionsItems[] =
{
	{0,0,0, (char*) 0,  	0, (MenuFunc)bt_srch_dev_pair,			isBtDevicePaired},
	{0,0,0, (char*) 0,	0, (MenuFunc)bt_srch_dev_pair,			isBtDeviceUnPaired},
	{0,0,0, (char*) 0,	0, (MenuFunc)bt_srch_dev_show_services,	item_flag_none},
	{0,0,0, (char*) 0,	0, (MenuFunc)bt_srch_dev_set_name,		isBtDeviceUnknown},		/* CQ21843 - Added Menu option*/
	{0,0,0, (char*) 0,	0, (MenuFunc)bt_srch_dev_add_known,		isBtDeviceKnown},
	{0,0,0, (char*) 0,	0, (MenuFunc)bt_srch_dev_rem_known,		isBtDeviceUnknown},
};

/*
** CQ22023 : The Menu attributes should not be const, because the Header Id is to change depending on the Device Name
**			Also MNU_HDRFORMAT_STR has to be added to the Menu Mode to allow a Real-Time string to be used as
**			the Header Id.
*/
static MfwMnuAttr menuBtDeviceOptions =
{
	&menuArea,
	MNU_LEFT | MNU_LIST | MNU_CUR_LINE | MNU_HDRFORMAT_STR, 	/* centered page menu       */
	-1,													/* use default font         */
	(MfwMnuItem*)menuBtDeviceOptionsItems,				/* with these items         */
	sizeof(menuBtDeviceOptionsItems)/sizeof(MfwMnuItem),	/* number of items          */
	COLOUR_LIST_XX,										/* Colour */
	TxtNull,												/* Hdr Id */
	NULL,												/* Background */
	MNUATTRSPARE										/* unused */
};

#if 0
static  MfwMnuItem menuBtServiceOptionsItems[] =
{
	{0,0,0, (char*) TxtBtAuthorize,  		0, (MenuFunc)bt_srch_serv_authorize,				isBtServiceTrusted},
	{0,0,0, (char*) TxtBtUnAuthorize,		0, (MenuFunc)bt_srch_serv_revoke_authorization,	isBtServiceNotTrusted},
};

static const MfwMnuAttr menuBtServiceOptions =
{
	&menuArea,
	MNU_LEFT | MNU_LIST | MNU_CUR_LINE,					/* centered page menu       */
	-1,													/* use default font         */
	(MfwMnuItem*)menuBtServiceOptionsItems,				/* with these items         */
	sizeof(menuBtServiceOptionsItems)/sizeof(MfwMnuItem),	/* number of items          */
	COLOUR_LIST_XX,										/* Colour */
	TxtNull,												/* Hdr Id */
	NULL,												/* Background */
	MNUATTRSPARE										/* unused */
};
#endif

/*
** Bluetooth defined Global Data
*/
T_MMI_BtData		bt_data = {0};

T_MMI_BtSearchData bt_srch_data = {0};

extern MfwHnd mainMmiLng;

#if 0
/*
** Test Specific Local Typedefs
*/
typedef void (*MfwBtCb) (int, void *);

/*
** Test Specific Local Defines
*/
#define mmiBtModTestDevMngr		1
#define mmiBtModTestDevMngrSrch	2
#define mmiBtModTestDevMngrSec		3
#define mmiBtModTestDataGw			4
#define mmiBtModTestAudioGw		5
#define mmiBtModTestObjPush		6
#define mmiBtModTestObjPushClient	7
#define mmiBtModTestObjPushServer	8
#define mmiBtModTestFileTxfr			9
#define mmiBtModTestFileTxfrClient	10
#define mmiBtModTestFileTxfrServer	11

/*
** Test Specific Local Static Data
*/
static int btModuleUnderTest = 0;
static MfwBtCb btModuleUnderTestCb = 0;


/*
** Module Test Function Definitoins
*/
/*******************************************************************************

 $Function:		bluetoothTestDevMngr

 $Description:		This function sets a flag for the Test Menu to indicate that it is the Device Manager
 				profile which is under test

 $Returns:		None

 $Arguments:		None

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

void bluetoothTestDevMngr (void)
{
	TRACE_EVENT("bluetoothTestDevMngr");
}

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

 $Function:		bluetoothTestDevMngrSrch

 $Description:		This function sets a flag for the Test Menu to indicate that it is the Device Manager
 				(Search) profile which is under test

 $Returns:		None

 $Arguments:		None

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

void bluetoothTestDevMngrSrch (void)
{
	TRACE_EVENT("bluetoothTestDevMngr");

	btModuleUnderTest = mmiBtModTestDevMngrSrch;
	btModuleUnderTestCb = (MfwBtCb)mfw_bt_Dm_Search_Cb;
}

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

 $Function:		bluetoothTestDevMngrSec

 $Description:		This function sets a flag for the Test Menu to indicate that it is the Device Manager
 				(Security) profile which is under test

 $Returns:		None

 $Arguments:		None

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

void bluetoothTestDevMngrSec (void)
{
	TRACE_EVENT("bluetoothTestDevMngr");

	btModuleUnderTest = mmiBtModTestDevMngrSec;
	btModuleUnderTestCb = (MfwBtCb)mfw_bt_Dm_Security_Cb;
}

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

 $Function:		bluetoothTestDataGw

 $Description:		This function sets a flag for the Test Menu to indicate that it is the Data Gateway
 				profile which is under test

 $Returns:		None

 $Arguments:		None

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

void bluetoothTestDataGw (void)
{
	TRACE_EVENT("bluetoothTestDataGw");

	btModuleUnderTest = mmiBtModTestDataGw;
}

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

 $Function:		bluetoothTestAudioGw

 $Description:		This function sets a flag for the Test Menu to indicate that it is the Audion Gateway
 				profile which is under test

 $Returns:		None

 $Arguments:		None

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

void bluetoothTestAudioGw (void)
{
	TRACE_EVENT("bluetoothTestAudioGw");

	btModuleUnderTest = mmiBtModTestAudioGw;
}

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

 $Function:		bluetoothTestObjPush

 $Description:		This function sets a flag for the Test Menu to indicate that it is the Object Push
 				profile which is under test

 $Returns:		None

 $Arguments:		None

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

void bluetoothTestObjPush (void)
{
	TRACE_EVENT("bluetoothTestObjPush");

	btModuleUnderTest = mmiBtModTestObjPush;
}

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

 $Function:		bluetoothTestFileTxfr

 $Description:		This function sets a flag for the Test Menu to indicate that it is the File Transfer
 				profile which is under test

 $Returns:		None

 $Arguments:		None

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

void bluetoothTestFileTxfr (void)
{
	TRACE_EVENT("bluetoothTestFileTxfr");

	btModuleUnderTest = mmiBtModTestFileTxfr;
}

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

 $Function:		bluetoothTestClient

 $Description:		This function sets a flag for the Test Menu to indicate that it is either the
 				Object Push or File Transfer Client profiles which are under test

 $Returns:		None

 $Arguments:		None

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

void bluetoothTestClient (void)
{
	TRACE_EVENT("bluetoothTestClient");

	if (btModuleUnderTest == mmiBtModTestObjPush)
	{
		btModuleUnderTest = mmiBtModTestObjPushClient;
		btModuleUnderTestCb = (MfwBtCb)mfw_bt_Opc_Cb;
	}
	else
	{
		btModuleUnderTest = mmiBtModTestFileTxfrClient;
		btModuleUnderTestCb = (MfwBtCb)mfw_bt_Ftc_Cb;
	}
}

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

 $Function:		bluetoothTestServer

 $Description:		This function sets a flag for the Test Menu to indicate that it is either the
 				Object Push or File Transfer Server profiles which are under test

 $Returns:		None

 $Arguments:		None

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

void bluetoothTestServer (void)
{
	TRACE_EVENT("bluetoothTestServer");

	if (btModuleUnderTest == mmiBtModTestObjPush)
	{
		btModuleUnderTest = mmiBtModTestObjPushServer;
		btModuleUnderTestCb = (MfwBtCb)mfw_bt_Ops_Cb;
	}
	else
	{
		btModuleUnderTest = mmiBtModTestFileTxfrServer;
		btModuleUnderTestCb = (MfwBtCb)mfw_bt_Fts_Cb;
	}
}

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

 $Function:		mmi_bluetooth_test_single_msg

 $Description:		This function test the sending of a single event via the appropriate profile callback

 $Returns:		None

 $Arguments:		mnu : pointer to the mnu data for the menu which caused this function to be called.
 				item : pointer to the item data from the menu.

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

GLOBAL int  mmi_bluetooth_test_single_msg (MfwMnu* mnu, MfwMnuItem* item)
{
	int event;
	U8 *sigData = mfwAlloc(sizeof(T_MFW_BT_SIG_DATA));

	TRACE_EVENT("mmi_bluetooth_test_single_msg");
	memset(sigData, 0x37, sizeof(T_MFW_BT_SIG_DATA));

	switch (btModuleUnderTest)
	{
		case mmiBtModTestDevMngrSrch:
			event = BTA_DM_INQ_RES_EVT;
			break;

		case mmiBtModTestDevMngrSec:
			event = BTA_DM_ENABLE_EVT;
			break;
			
		case mmiBtModTestDataGw:
			event = BTA_DG_LISTEN_EVT;
			break;

		case mmiBtModTestAudioGw:
			event = BTA_AG_OPEN_EVT;
			break;

		case mmiBtModTestObjPushClient:
			event = BTA_OPC_OBJECT_EVT;
			break;

		case mmiBtModTestObjPushServer:
			event = BTA_OPS_CLOSE_EVT;
			break;

		case mmiBtModTestFileTxfrClient:
			event = BTA_FTC_ENABLE_EVT;
			break;

		case mmiBtModTestFileTxfrServer:
			event = BTA_FTS_AUTH_EVT;
			break;

		default:
			TRACE_EVENT("mmi_bluetooth_test_single_msg > Invalid Test Module");
			mfwFree(sigData, sizeof(T_MFW_BT_SIG_DATA));
			return 1;
	}

	btModuleUnderTestCb(BTA_DG_LISTEN_EVT, sigData);

	mfwFree(sigData, sizeof(T_MFW_BT_SIG_DATA));
	return 1;
}

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

 $Function:		mmi_bluetooth_test_multi_msg

 $Description:		This function test the sending of a multiple events via the appropriate profile callback

 $Returns:		None

 $Arguments:		mnu : pointer to the mnu data for the menu which caused this function to be called.
 				item : pointer to the item data from the menu.

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

GLOBAL int  mmi_bluetooth_test_multi_msg (MfwMnu* mnu, MfwMnuItem* item)
{
	U8 *sigData = mfwAlloc(sizeof(T_MFW_BT_SIG_DATA));
	int	iLoop, iLoopMaxVal;
	unsigned char chInit;

	TRACE_EVENT("mmi_bluetooth_test_multi_msg");

	chInit = 0x41;

	switch (btModuleUnderTest)
	{
		case mmiBtModTestDevMngrSrch:
			iLoopMaxVal = BTA_DM_DISC_CMPL_EVT;
			break;

		case mmiBtModTestDevMngrSec:
			iLoopMaxVal = BTA_DM_SIG_STRENGTH_EVT;
			break;
			
		case mmiBtModTestDataGw:
			iLoopMaxVal = BTA_DG_CLOSE_EVT;
			break;

		case mmiBtModTestAudioGw:
			iLoopMaxVal = BTA_AG_AT_CNUM_EVT;
			break;

		case mmiBtModTestObjPushClient:
			iLoopMaxVal = BTA_OPC_CLOSE_EVT;
			break;

		case mmiBtModTestObjPushServer:
			iLoopMaxVal = BTA_OPS_CLOSE_EVT;
			break;

		case mmiBtModTestFileTxfrClient:
			iLoopMaxVal = BTA_FTC_GETFILE_EVT;
			break;

		case mmiBtModTestFileTxfrServer:
			iLoopMaxVal = BTA_FTS_AUTH_EVT;
			break;

		default:
			TRACE_EVENT("mmi_bluetooth_test_multi_msg > Invalid Test Module");
			mfwFree(sigData, sizeof(T_MFW_BT_SIG_DATA));
			return 1;
	}

	for (iLoop = 0; iLoop <= iLoopMaxVal; iLoop++)
	{
		chInit++;
		memset(sigData, chInit, sizeof(T_MFW_BT_SIG_DATA));
		
		btModuleUnderTestCb(iLoop, sigData);
	}

	mfwFree(sigData, sizeof(T_MFW_BT_SIG_DATA));

	return 1;
}

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

 $Function:		mmi_bluetooth_test_buf_ovrflow

 $Description:		This function testS the sending of a multiple events via the appropriate profile callback,
 				causing a buf overflow of the event buffer

 $Returns:		None

 $Arguments:		mnu : pointer to the mnu data for the menu which caused this function to be called.
 				item : pointer to the item data from the menu.

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

GLOBAL int  mmi_bluetooth_test_buf_ovrflow(MfwMnu* mnu, MfwMnuItem* item)
{
	int event;
	U8 *sigData = mfwAlloc(sizeof(T_MFW_BT_SIG_DATA));
	int	iLoop, iLoopMaxVal;
	unsigned char chInit;

	TRACE_EVENT("mmi_bluetooth_test_multi_msg");

	chInit = 0x61;

	switch (btModuleUnderTest)
	{
		case mmiBtModTestDevMngrSrch:
			iLoopMaxVal = BTA_DM_DISC_CMPL_EVT;
			break;

		case mmiBtModTestDevMngrSec:
			iLoopMaxVal = BTA_DM_SIG_STRENGTH_EVT;
			break;
			
		case mmiBtModTestDataGw:
			iLoopMaxVal = BTA_DG_CLOSE_EVT;
			break;

		case mmiBtModTestAudioGw:
			iLoopMaxVal = BTA_AG_AT_CNUM_EVT;
			break;

		case mmiBtModTestObjPushClient:
			iLoopMaxVal = BTA_OPC_CLOSE_EVT;
			break;

		case mmiBtModTestObjPushServer:
			iLoopMaxVal = BTA_OPS_CLOSE_EVT;
			break;

		case mmiBtModTestFileTxfrClient:
			iLoopMaxVal = BTA_FTC_GETFILE_EVT;
			break;

		case mmiBtModTestFileTxfrServer:
			iLoopMaxVal = BTA_FTS_AUTH_EVT;
			break;

		default:
			TRACE_EVENT("mmi_bluetooth_test_multi_msg > Invalid Test Module");
			mfwFree(sigData, sizeof(T_MFW_BT_SIG_DATA));
			return 1;
	}


	event  = 0;
	for (iLoop = 0; iLoop <= MFW_BT_MAX_SIG_Q_ENTRIES+1; iLoop++)
	{
		chInit++;
		memset(sigData, chInit, sizeof(T_MFW_BT_SIG_DATA));
		
		btModuleUnderTestCb(event, sigData);
		event++;
		if (event > iLoopMaxVal)
			event = 0;
	}

	mfwFree(sigData, sizeof(T_MFW_BT_SIG_DATA));

	return 1;
}
#endif

/*
** Module Function Definitions
*/

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

 $Function:		isBluetoothActive

 $Description:		This function checks to determine whether Bluetooth is enabled

 $Returns:		USHORT : 1 is Bluetooth is Enabled, 0 otherwise

 $Arguments:		Not Used.

*******************************************************************************/
USHORT isBluetoothActive( struct MfwMnuTag *m, struct MfwMnuAttrTag *ma, struct MfwMnuItemTag *mi )
{
	MFW_BT_TRACE("isBluetoothActive()");

	if (bt_data.bt_isActive)
		return 1;
	
	return 0;
}

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

 $Function:		isBluetoothInactive

 $Description:		This function checks to determine whether Bluetooth is disabled

 $Returns:		USHORT : 1 is Bluetooth is Disabled, 0 otherwise

 $Arguments:		Not Used.

*******************************************************************************/
USHORT isBluetoothInactive ( struct MfwMnuTag *m, struct MfwMnuAttrTag *ma, struct MfwMnuItemTag *mi )
{
	MFW_BT_TRACE("isBluetoothInactive()");

	if (bt_data.bt_isActive == FALSE)
		return 1;

	return 0;
}


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

 $Function:		mmi_bluetooth_automatic

 $Description:		This function performs the necessary steps to enable bluetooth. It creates a dialog,
 				with the MfwRoot as the parent, and calls the MFW BT functions

 $Returns:		Always returnd MFW_EVENT_CONSUMED (1)

 $Arguments:		mnu : pointer to the mnu data for the menu which caused this function to be called.
 				item : pointer to the item data from the menu.

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

GLOBAL int mmi_bluetooth_automatic (MfwMnu * mnu, MfwMnuItem * item)
{
	T_MFW_HND win = mfw_parent(mfw_header());

	MFW_BT_TRACE("mmi_bluetooth_automatic()");

	/*
	** Create a timed dialog to display the Message "Bluetooth Failed"
	*/
	mmi_bluetooth_show_info(win, TxtNotAvailable, TxtNull);
}

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

 $Function:		isBtDevicePaired

 $Description:		This function checks to determine whether the active device is Paired or not.

 $Returns:		USHORT : 1 is Device is Paired, 0 otherwise

 $Arguments:		Not Used.

*******************************************************************************/
USHORT isBtDevicePaired ( MfwMnu *m, MfwMnuAttr *ma, MfwMnuItem *mi )
{
	T_MFW_BT_REM_DEVICE_INFO *cur_device = &bt_srch_data.srch_bt_dev_list[bt_srch_data.srch_bt_cur_dev_idx];

	MFW_BT_TRACE("isBtDevicePaired()");
	
	if (cur_device->link_key_present != FALSE)
		return 1;

	return 0;
}

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

 $Function:		isBtDeviceUnPaired

 $Description:		This function is the opposite of isBtDevicePaired (above)

 $Returns:		USHORT : 1 is Device is Not Paired, 0 otherwise

 $Arguments:		Not Used.

*******************************************************************************/
USHORT isBtDeviceUnPaired( MfwMnu *m, MfwMnuAttr *ma, MfwMnuItem *mi )
{
	T_MFW_BT_REM_DEVICE_INFO *cur_device = &bt_srch_data.srch_bt_dev_list[bt_srch_data.srch_bt_cur_dev_idx];

	MFW_BT_TRACE("isBtDeviceUnPaired()");

	if (cur_device->link_key_present != FALSE)
		return 0;

	return 1;
}

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

 $Function:		isBtDeviceKnown

 $Description:		This function checks to determine whether the active device is Known or not.

 $Returns:		USHORT : 1 is Device is Known, 0 otherwise

 $Arguments:		Not Used.

*******************************************************************************/
USHORT isBtDeviceKnown( MfwMnu *m, MfwMnuAttr *ma, MfwMnuItem *mi )
{
	T_MFW_BT_REM_DEVICE_INFO *cur_device = &bt_srch_data.srch_bt_dev_list[bt_srch_data.srch_bt_cur_dev_idx];

	MFW_BT_TRACE("isBtDeviceKnown()");

	if (cur_device->is_new == FALSE)
		return 1;

	return 0;
}

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

 $Function:		isBtDeviceUnknown

 $Description:		This function is the opposite of isBtDeviceKnown (above).

 $Returns:		USHORT : 1 is Device is Not Known, 0 otherwise

 $Arguments:		Not Used.

*******************************************************************************/
USHORT isBtDeviceUnknown( MfwMnu *m, MfwMnuAttr *ma, MfwMnuItem *mi )
{
	T_MFW_BT_REM_DEVICE_INFO *cur_device = &bt_srch_data.srch_bt_dev_list[bt_srch_data.srch_bt_cur_dev_idx];

	MFW_BT_TRACE("isBtDeviceUnknown()");

	if (cur_device->is_new == FALSE)
		return 0;

	return 1;
}

/*
** CQ 21834 : The following function is required to hide a Known Device in the List whem it is removed
** 			 from the Known Devices Database
*/
/*******************************************************************************

 $Function:		isListDeviceUnknown

 $Description:		This function is determines whether the current device in the known device list
 				is still in the Known Devices Database.

 $Returns:		USHORT : 1 is Device is Not Known, 0 otherwise

 $Arguments:		Not Used.

*******************************************************************************/
USHORT isListDeviceUnknown( MfwMnu *m, MfwMnuAttr *ma, MfwMnuItem *mi )
{
	int index;
	int indexFound = 0;
	MfwMnuItem *mItem;
	T_MFW_BT_REM_DEVICE_INFO *cur_device;

	index = 0;
	while ((indexFound == 0) && (index < ma->nItems))
	{
		mItem = &(ma->items[index]);

		if (mItem == mi)
			indexFound = 1;
		else
			index++;
	}

	if (indexFound == 1)
	{
		MFW_BT_TRACE_P1("isListDeviceUnknown()  index = %d", index);
	}
	else
	{
		MFW_BT_TRACE("isListDeviceUnknown()  : Unable to determine Index");
	}

	cur_device = &bt_srch_data.srch_bt_dev_list[index];

	if (cur_device->is_new == FALSE)
		return 0;

	return 1;
}

/*
** CQ 21834 : The following function is required to determine whether a "No Devices" entry in the
**			 Known Devices list should be visible. Without the "No Devices" Entry the list would
**			 be empty, and this is not handled correctly in the BMI.
*/
/*******************************************************************************

 $Function:		isDeviceListEmpty

 $Description:		This function determines whether there are any entries in the known devices
 				database.

 $Returns:		USHORT : 0 if the Known Device Database is Empty, 1 otherwise.

 $Arguments:		Not Used.

*******************************************************************************/
USHORT isDeviceListEmpty( MfwMnu *m, MfwMnuAttr *ma, MfwMnuItem *mi )
{
	int index;
	T_MFW_BT_REM_DEVICE_INFO *cur_device;
	T_MFW_WIN	* win_data;
	ListWinInfo	* data;

	MFW_BT_TRACE("isDeviceListEmpty()");
	
	for (index = 0; index < (ma->nItems -1); index++)
	{
		cur_device = &bt_srch_data.srch_bt_dev_list[index];

		if (cur_device->is_new == FALSE)
			return 1;
	}

	/*
	** The list is otherwise empty so :
	** 	1. remove the left soft key
	**	2. ensure that the "No Devices" entry is displayed
	*/
	
	win_data = ((T_MFW_HDR *)bt_srch_data.srch_bt_dev_list_win)->data;
	data = (ListWinInfo *)win_data->user;

	data->MenuData.LeftSoftKey = TxtNull;
	return 0;
}


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

 $Function:		mmi_bt_init

 $Description:		This function initializes the Bluetooth functionality on MMI startup

 $Returns:		none

 $Arguments:		none.

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

void  mmi_bt_exit (void)
{
	T_MMI_BtData		*data = &bt_data;
	
	MFW_BT_TRACE("mmi_bt_exit()");
	if (data->bt_isEnabled == FALSE)
		return;
	
	mfw_bt_delete(data->bt_win);
	timDelete(data->bt_discoverable_timer);
	timDelete(data->bt_connection_timer);

	mfw_bt_exit();

	return;
}

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

 $Function:		mmi_bt_init

 $Description:		This function initializes the Bluetooth functionality on MMI startup

 $Returns:		none

 $Arguments:		none.

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

void mmi_bt_init (void)
{
	T_MMI_BtData		*data = &bt_data;
	
	MFW_BT_TRACE("mmi_bt_init()");
	
	mfw_bt_init();			/* Initialize Bluetooth Module */


	data->bt_isEnabled = TRUE;

	/*
	** Create a Bluetooth component
	*/
	MFW_BT_TRACE("mmi_bt_init > Creating the MFW_BT component");

	if (data->bt_win == (void *)0)
	{
		data->bt_win = mfw_bt_create(0, E_BT_ALL_SERVICES, (MfwCb)mmi_bluetooth_root_cb);
	}

	if (data->bt_win == (void *)0)
	{
		MFW_BT_TRACE("mmi_bt_init > MFW_BT Component Failure");
		data->bt_isEnabled = FALSE;
	}
	else
	{

		/*
		** Create a Timer component for the "Discoverable" Timeout
		*/
		MFW_BT_TRACE("mmi_bt_init > Creating the discoverable timer");
		if (data->bt_discoverable_timer == (void *)0)
			data->bt_discoverable_timer = timCreate(0,
												BT_DISCOVERABLE_DURATION,
												(MfwCb)mmi_bluetooth_discovery_timer_cb);

		if (data->bt_discoverable_timer == (void *)0)
		{
			MFW_BT_TRACE("mmi_bt_init > Discoverable timer creation failed ");
			data->bt_isEnabled = FALSE;
			/*
			** Timer Compnonent Failed to start, delete previous components
			*/
			mfw_bt_delete(data->bt_win);
		}
		else
		{

			/*
			** Create a Timer component for the "Connection" Timeout, when the timeout expires
			** for the device being discoverable, but the is still a BT connection in progress
			*/
			MFW_BT_TRACE("mmi_bt_init > Creating the connection timer");
			if (data->bt_connection_timer == (void *)0)
				data->bt_connection_timer = timCreate(0,
												     BT_CONNECTION_DURATION,
												     (MfwCb)mmi_bluetooth_connection_timer_cb);
			if (data->bt_connection_timer == (void *)0)
			{
				MFW_BT_TRACE("mmi_bt_init > Connection Timer creation failure");
				data->bt_isEnabled = FALSE;
				/*
				** Timer Compnonent Failed to start, delete previous components
				*/
				mfw_bt_delete(data->bt_win);
				timDelete(data->bt_discoverable_timer);
			}
			else
			{
				menuBtDeviceOptionsItems[0].str = MmiRsrcGetText(TxtBtPairDevice);
				menuBtDeviceOptionsItems[1].str = MmiRsrcGetText(TxtBtChangePassKey);
				menuBtDeviceOptionsItems[2].str = MmiRsrcGetText(TxtBtShowServices);
				menuBtDeviceOptionsItems[3].str = MmiRsrcGetText(TxtBtSetLocalName);	/* CQ21843 - Menu Entry to Allow setting the Friendly Name */
				menuBtDeviceOptionsItems[4].str = MmiRsrcGetText(TxtBtAddToKnown);
				menuBtDeviceOptionsItems[5].str = MmiRsrcGetText(TxtBtRemoveDevice);
			}
		}
	}
	return;
	
}

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

 $Function:		mmi_bluetooth_on

 $Description:		This function performs the necessary steps to turn on bluetooth. It will create the
 				root window if required

 $Returns:		Always returnd MFW_EVENT_CONSUMED (1)

 $Arguments:		mnu : pointer to the mnu data for the menu which caused this function to be called.
 				item : pointer to the item data from the menu.

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

GLOBAL int  mmi_bluetooth_on (MfwMnu* mnu, MfwMnuItem* item)
{
#if 1 /* Disable this while developing the test harness ... it'll come later */

	T_MFW_BT_STATUS btRetVal;

	MFW_BT_TRACE("mmi_bluetooth_on()");

	if (bt_data.bt_isEnabled == FALSE)
	{
		/*
		** Create a timed dialog to display the Message "Bluetooth DeActivated"
		*/
		mmi_bluetooth_show_info(0, TxtBluetooth, TxtDeActivated);
	}
	else
	{
		btRetVal = mfw_bt_enable(MFW_BT_DEFAULT_VIS);

		if (btRetVal != MFW_BT_SUCCESS)
		{
			MFW_BT_TRACE_P1("mmi_bluetooth() : Attempt to enable Bluetooth Failed with %d", btRetVal);
			/*
			** Create a timed dialog to display the Message "Bluetooth Failed"
			*/
			mmi_bluetooth_show_info(0, TxtBluetooth, TxtFailed);
		}
	}

	
#else
	T_MFW_BT_STATUS mfwBtRetVal;

	mfwBtRetVal = mfw_bt_ge_enable();

	if (mfwBtRetVal <= 0)
	{
		/*
		** Create a timed dialog to display the Message "Bluetooth Failed"
		*/
		mmi_bluetooth_show_info(TxtBluetooth, TxtFailed);
	}
	else
	{
		/*
		** Create a timed dialog to display the Message "Bluetooth Activated"
		*/
		mmi_bluetooth_show_info(TxtBluetooth, TxtActivated);
	}
	
#endif

	return MFW_EVENT_CONSUMED;
	
}

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

 $Function:		mmi_bluetooth_off

 $Description:		This function performs the necessary steps to turn off bluetooth

 $Returns:		MFW_EVENT_CONSUMED

 $Arguments:		mnu : pointer to the mnu data for the menu which caused this function to be called.
 				item : pointer to the item data from the menu.

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

GLOBAL int  mmi_bluetooth_off (MfwMnu* mnu, MfwMnuItem* item)
{
#if 1	/* Disable this while developing the test harness ... it'll come later */
	T_MMI_BtData		*data = &bt_data;

	MFW_BT_TRACE("mmi_bluetooth_off()");

	if (data->bt_isEnabled == FALSE)
	{
		return MFW_EVENT_CONSUMED;
	}
	else
	{
		if (data->bt_isActive != FALSE)
		{
			/*
			** Disable the Bluetooth module
			*/
			mfw_bt_disable();

			timStop(data->bt_discoverable_timer);
			timStop(data->bt_connection_timer);
		}
	}
#else
	mfw_bt_Ge_Disable();

	/*
	** Create a timed dialog to display the Message "Bluetooth DeActivated"
	*/
	mmi_bluetooth_show_info(TxtBluetooth, TxtDeActivated);

#endif

	return MFW_EVENT_CONSUMED;
}

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

 $Function:		mmi_bluetooth_change_name

 $Description:		This function performs the necessary steps to change the name of the local device.
 				It will start an editor to prompt for the name, and allow the user to cancel the input.

 $Returns:		MFW_EVENT_CONSUMED

 $Arguments:		mnu : pointer to the mnu data for the menu which caused this function to be called.
 				item : pointer to the item data from the menu.

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

GLOBAL int  mmi_bluetooth_change_name(MfwMnu * mnu, MfwMnuItem * item)
{
	T_MFW_BT_STATUS btRetVal;
	T_MMI_BtData *data = &bt_data;
	
	MfwHnd win = mfw_parent(mfw_header());

	MFW_BT_TRACE("mmi_bluetooth_change_name()");	/* CQ21835 */

	if (data->bt_isEnabled == FALSE)
	{
		/*
		** Create a timed dialog to display the Message "Bluetooth DeActivated"
		*/
		mmi_bluetooth_show_info(0, TxtBluetooth, TxtDeActivated);
	}
	else if (data->bt_dev_name_win == (void *)0)
	{
		data->bt_DevNameForStartup = FALSE;

		data->bt_dev_name_win = mmi_bt_dev_name_create(win);

		if (data->bt_dev_name_win != (void *)0)
		{
			SEND_EVENT(data->bt_dev_name_win, BT_DEV_NAME_REQ, 0, (void *)0);
		}
		else
		{
			MFW_BT_TRACE("mmi_bluetooth_root_cb() : Unable to create Device Name Win!");
		}
	}
	else
	{
		MFW_BT_TRACE("mmi_bluetooth_root_cb() : Device Name Win already active");
	}

	return MFW_EVENT_CONSUMED;

}

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

 $Function:		mmi_bluetooth_set_discoverable_on

 $Description:		This function performs the necessary steps to make this device discoverable, it
 				will turn on Bluetooth if it is currently off.

 $Returns:		MFW_EVENT_CONSUMED

 $Arguments:		mnu : pointer to the mnu data for the menu which caused this function to be called.
 				item : pointer to the item data from the menu.

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

GLOBAL int  mmi_bluetooth_set_discoverable_on(MfwMnu * mnu, MfwMnuItem * item)
{
	T_MFW_BT_STATUS btRetVal;
	T_MMI_BtData *data = &bt_data;

	MFW_BT_TRACE("mmi_bluetooth_set_discoverable_on()");

	if (data->bt_isEnabled == FALSE)
	{
		/*
		** Create a timed dialog to display the Message "Bluetooth DeActivated"
		*/
		mmi_bluetooth_show_info(0, TxtBluetooth, TxtDeActivated);
	}
	else
	{
		timStop(data->bt_discoverable_timer);
		timStop(data->bt_connection_timer);
		btRetVal = mfw_bt_dm_set_visibility(TRUE, FALSE);	/* Shown, and permanently on */

		if (btRetVal != MFW_BT_SUCCESS)
		{
			MFW_BT_TRACE_P1("mmi_bluetooth_set_discoverable_on() : Set Visibility (TRUE) failed with status : %d", btRetVal);
			/*
			** Create a timed dialog to display the Message "Failed"
			*/
			mmi_bluetooth_show_info(0, TxtFailed, TxtNull);
		}
		else
		{
			if (data->bt_isActive == FALSE)
			{
				/*
				** Enable Bluetooth with the appropriate Visibility Mask
				*/
				btRetVal = mfw_bt_enable(MFW_BT_SHOWN);

				if (btRetVal != MFW_BT_SUCCESS)
				{
					MFW_BT_TRACE_P1("mmi_bluetooth_set_discoverable_on() : Attempt to enable Bluetooth Failed with %d", btRetVal);
					/*
					** Create a timed dialog to display the Message "Failed"
					*/
					mmi_bluetooth_show_info(0, TxtFailed, TxtNull);
				}
			}
			else
			{
				/*
				** Create a timed dialog to display the Message "Device Discoverable"
				*/
				mmi_bluetooth_show_info(0, TxtBtDevice, TxtBtDiscoverable);
			}
		}
	}

	return MFW_EVENT_CONSUMED;
}

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

 $Function:		mmi_bluetooth_set_discoverable_timed

 $Description:		This function performs the necessary steps to make this device discoverable
 				for a preconfigured amount of time. It bluetooth is Off, it will be started. When
 				the time expiures, thew devicde will become hidden. If there is a connection
 				open, and bluetooth was started as a result of this request, the timer will be reset,
 				and when it expires with no connection active, bluetooth will be deactivated.

 $Returns:		MFW_EVENT_CONSUMED

 $Arguments:		mnu : pointer to the mnu data for the menu which caused this function to be called.
 				item : pointer to the item data from the menu.

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

GLOBAL int  mmi_bluetooth_set_discoverable_timed(MfwMnu * mnu, MfwMnuItem * item)
{
	T_MFW_BT_STATUS btRetVal;
	T_MMI_BtData *data = &bt_data;

	MFW_BT_TRACE("mmi_bluetooth_set_discoverable_timed()");

	if (data->bt_isEnabled == FALSE)
	{
		/*
		** Create a timed dialog to display the Message "Bluetooth DeActivated"
		*/
		mmi_bluetooth_show_info(0, TxtBluetooth, TxtDeActivated);
	}
	else if (data->bt_isActive == FALSE)
	{
		/*
		** Enable Bluetooth with the appropriate Visibility Mask
		*/
		btRetVal = mfw_bt_enable(MFW_BT_SHOWN);

		if (btRetVal != MFW_BT_SUCCESS)
		{
			MFW_BT_TRACE_P1("mmi_bluetooth_set_discoverable_timed() : Attempt to enable Bluetooth Failed with %d", btRetVal);
			/*
			** Create a timed dialog to display the Message "Failed"
			*/
			mmi_bluetooth_show_info(0, TxtFailed, TxtNull);
		}
		else
			data->bt_stopBtOnDiscoverableTimeout = TRUE;
	}
	else
	{
		btRetVal = mfw_bt_dm_set_visibility(TRUE, TRUE);

		if (btRetVal != MFW_BT_SUCCESS)
		{
			MFW_BT_TRACE_P1("mmi_bluetooth_set_discoverable_timed() : Set Visibility (TRUE) failed with status : %d", btRetVal);
			/*
			** Create a timed dialog to display the Message "Failed"
			*/
			mmi_bluetooth_show_info(0, TxtFailed, TxtNull);
		}
		else
		{
			/*
			** Create a timed dialog to display the Message "Device Discoverable"
			*/
			mmi_bluetooth_show_info(0, TxtBtDevice, TxtBtDiscoverable);
			data->bt_stopBtOnDiscoverableTimeout = FALSE;
		}
	}

	timStart(data->bt_discoverable_timer);

	return MFW_EVENT_CONSUMED;
}

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

 $Function:		mmi_bluetooth_set_discoverable_off

 $Description:		This function performs the necessary steps to make this device hidden. It
 				will not change the state of Bluetooth, if it is on, it will remain on, but hidden,
 				if it is Off it will remain off.

 $Returns:		MFW_EVENT_CONSUMED

 $Arguments:		mnu : pointer to the mnu data for the menu which caused this function to be called.
 				item : pointer to the item data from the menu.

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

GLOBAL int  mmi_bluetooth_set_discoverable_off(MfwMnu * mnu, MfwMnuItem * item)
{
	T_MFW_BT_STATUS btRetVal;
	T_MMI_BtData *data = &bt_data;

	MFW_BT_TRACE("mmi_bluetooth_set_discoverable_off()");

	if (data->bt_isEnabled == FALSE)
	{
		/*
		** Create a timed dialog to display the Message "Bluetooth DeActivated"
		*/
		mmi_bluetooth_show_info(0, TxtBluetooth, TxtDeActivated);
	}
	else
	{
		timStop(data->bt_discoverable_timer);
		timStop(data->bt_connection_timer);

		btRetVal = mfw_bt_dm_set_visibility(FALSE, FALSE);

		if (btRetVal != MFW_BT_SUCCESS)
		{
			MFW_BT_TRACE_P1("mmi_bluetooth() : Set Visibility (FALSE) failed with status : %d", btRetVal);
			/*
			** Create a timed dialog to display the Message "Failed"
			*/
			mmi_bluetooth_show_info(0, TxtFailed, TxtNull);
		}
		else
		{
			mmi_bluetooth_show_info(0, TxtBtDevice, TxtBtHidden);
		}
	}
	return MFW_EVENT_CONSUMED;
}

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

 $Function:		mmi_bluetooth_device_search

 $Description:		This function performs the necessary steps to search for local bluetooth devices.
 				It will only be avaiable if in the menu Bluetooth is active. It will start a new window
 				to specifically handle the search.

 $Returns:		MFW_EVENT_CONSUMED

 $Arguments:		mnu : pointer to the mnu data for the menu which caused this function to be called.
 				item : pointer to the item data from the menu.

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

GLOBAL int  mmi_bluetooth_device_search(MfwMnu * mnu, MfwMnuItem * item)
{
	T_MFW_HND win;
	T_MFW_BT_STATUS btRetVal;
	T_MMI_BtData *data = &bt_data;
	T_MMI_BtSearchData *srch_data = &bt_srch_data;

	MFW_BT_TRACE("mmi_bluetooth_device_search()");

	if (data->bt_isActive == FALSE)
	{
		/*
		** Create a timed dialog to display the Message "Bluetooth DeActivated"
		*/
		mmi_bluetooth_show_info(0, TxtBluetooth, TxtDeActivated);
		return MFW_EVENT_CONSUMED;
	}
	
	if (srch_data->win == (void *)0)
	{
		win = mfw_parent(mfw_header());
		
		if (mmi_bt_search_create(win) == FALSE)
		{
			/*
			** Create a timed dialog to display the Message "Failed"
			*/
			mmi_bluetooth_show_info(0, TxtFailed, TxtNull);
			return MFW_EVENT_CONSUMED;
		}
		SEND_EVENT(srch_data->win, BT_DEVICE_SEARCH, 0, 0);
	}
	else
	{
		MFW_BT_TRACE("mmi_bluetooth_device_search > win not NULL!!!");
		
	}
	
	return MFW_EVENT_CONSUMED;
}

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

 $Function:		mmi_bluetooth_list_known_devices

 $Description:		This function performs the necessary steps to search for local bluetooth devices.
 				It will only be avaiable if in the menu Bluetooth is active. It will start a new window
 				to specifically handle the search.

 $Returns:		MFW_EVENT_CONSUMED

 $Arguments:		mnu : pointer to the mnu data for the menu which caused this function to be called.
 				item : pointer to the item data from the menu.

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

GLOBAL int  mmi_bluetooth_list_known_devices(MfwMnu * mnu, MfwMnuItem * item)
{
	T_MFW_HND win;
	T_MFW_BT_STATUS btRetVal;
	T_MMI_BtData *data = &bt_data;
	T_MMI_BtSearchData *srch_data = &bt_srch_data;

	MFW_BT_TRACE("mmi_bluetooth_list_known_devices()");

	if (data->bt_isEnabled == FALSE)
	{
		/*
		** Create a timed dialog to display the Message "Bluetooth DeActivated"
		*/
		mmi_bluetooth_show_info(0, TxtBluetooth, TxtDeActivated);
		return MFW_EVENT_CONSUMED;
	}

	if (srch_data->win == (void *)0)
	{
		win = mfw_parent(mfw_header());
		
		if (mmi_bt_search_create(win) == FALSE)
		{
			/*
			** Create a timed dialog to display the Message "Failed"
			*/
			mmi_bluetooth_show_info(0, TxtFailed, TxtNull);
			return MFW_EVENT_CONSUMED;
		}
	}

	SEND_EVENT(srch_data->win, BT_LIST_KNOWN_DEVICES, 0, 0);

	return MFW_EVENT_CONSUMED;
}


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

 $Function:		mmi_bluetooth_clear_all_stored_devices

 $Description:		This function clears all stored devices from FFS.

 $Returns:		MFW_EVENT_CONSUMED

 $Arguments:		mnu : pointer to the mnu data for the menu which caused this function to be called.
 				item : pointer to the item data from the menu.

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

GLOBAL int  mmi_bluetooth_clear_all_stored_devices(MfwMnu * mnu, MfwMnuItem * item)
{
	T_MFW_BT_STATUS btRetVal;
	T_MFW_BT_REM_DEVICE *cur_device;
	T_MFW_BT_REM_DEVICE *ptr_db_device[MFW_BT_NUM_REM_DEVICE];
	UINT8 dev_index;
	UINT8 num_of_known_devices;

	MFW_BT_TRACE("mmi_bluetooth_clear_all_stored_devices()");

	if (bt_data.bt_isEnabled == FALSE)
	{
		/*
		** Create a timed dialog to display the Message "Bluetooth DeActivated"
		*/
		mmi_bluetooth_show_info(0, TxtBluetooth, TxtDeActivated);
		return MFW_EVENT_CONSUMED;
	}

	mfw_bt_get_device_by_service(BTA_ALL_SERVICE_MASK, &ptr_db_device[0], &num_of_known_devices);
	
	for (dev_index = 0; dev_index < num_of_known_devices; dev_index++)
	{
		cur_device = ptr_db_device[dev_index];
		
		btRetVal = mfw_bt_dm_delete_device(cur_device->bd_addr);

		if (btRetVal != MFW_BT_SUCCESS)
		{
			MFW_BT_TRACE_P1("mfw_bt_dm_clear_all_stored_dev returned error : %d", btRetVal);
			mmi_bluetooth_show_info(0, TxtFailed, TxtNull);
			return MFW_EVENT_CONSUMED;
		}
	}
		
	mmi_bluetooth_show_info(0, TxtBtKnownDevices, TxtDeleted);

	return MFW_EVENT_CONSUMED;
}

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

 $Function:		mmi_bt_pin_request_create

 $Description:		This function performs the necessary steps to create the a window to handle the
 				PIN Request, pairing process. It will be removed, or rather remove itself on receipt
 				of the AUTH_CMPL event
 				
 $Returns:		T_MFW_HND : Window Handle to th eNew Window, Null if failed.

 $Arguments:		parent : pointer to the parent window.

*******************************************************************************/
T_MFW_HND mmi_bt_pin_request_create(T_MFW_HND parent)
{
	T_MMI_BT_PIN_Req_Data *data;
	T_MFW_WIN * win;

	data = (T_MMI_BT_PIN_Req_Data *)mfwAlloc((U16)sizeof(T_MMI_BT_PIN_Req_Data));

	if (data == (void *)0)
		return data;

	data->win = winCreate(parent, 0, E_WIN_VISIBLE, mmi_bluetooth_win_cb);

	if (data->win == (void *)0)
	{
		/*
		** Failed to start : Free Memory, and exit
		*/
		mfwFree((U8 *)data, (U16)sizeof(T_MMI_BT_PIN_Req_Data));
		data = (void *)0;
		return data;
	}
	else
	{
		/*
		** Setup the Dialog control functions
		*/
		data->mmi_control.dialog = (T_DIALOG_FUNC)mmi_bt_pin_req_cntrl;
		data->mmi_control.data = data;
		
		win = ((T_MFW_HDR *)data->win)->data;
		win->user = (void *)data;
	}

	bt_data.bt_pin_req_win = data->win;
	return data->win;

}

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

 $Function:		mmi_bluetooth_pin_request_destroy

 $Description:		This function performs the necessary steps to remove the window handling the
 				PIN request, tidying up all allocated resources.

 $Returns:		MfwResOk : Success
 				MfwResIllHnd : Illegal Window Handler provided

 $Arguments:		win : Window to be destroyed

*******************************************************************************/
MfwRes mmi_bt_pin_request_destroy(T_MFW_HND win)
{
	T_MFW_WIN * win_data;
	T_MMI_BT_PIN_Req_Data * data;

	if (win == (void *)0)
		return MfwResIllHnd;

	win_data = ((T_MFW_HDR *) win)->data;
	data = (T_MMI_BT_PIN_Req_Data *)win_data->user;

	/*
	** Destroy the Window
	*/
	win_delete(data->win);

	/*
	** Free the dynamically allocated memory
	*/
	mfwFree((U8 *)data, (U16)sizeof(T_MMI_BT_PIN_Req_Data));

	bt_data.bt_pin_req_win = (void *)0;

	return MfwResOk;
}


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

 $Function:		mmi_bt_pin_req_cntrl

 $Description:		This is the dialog control function for the Pin REquest Window. It receives the signals
 				from the MFW and determines what action, if any, to take.

 $Returns:		None

 $Arguments:		win :		The pointer to the window handler, so the function can reference the
							dynamic user data, if any.
 				event :		The incoming event
 				value :		Generic incoming Parameter, it will be 'event' dependant
 				parameter :	Generic incoming Parameter, it will be 'event' dependant

*******************************************************************************/
void mmi_bt_pin_req_cntrl (T_MFW_HND win, USHORT event, SHORT value, void * parameter)
{
	T_MFW_WIN			* win_data = ((T_MFW_HDR *) win)->data;
	T_MMI_BT_PIN_Req_Data * data = (T_MMI_BT_PIN_Req_Data *)win_data->user;

	T_AUI_EDITOR_DATA	editor_data;
	T_MFW_BT_STATUS		btRetVal;
	
	T_MFW_BT_DM_PIN_REQ	*pin_req_param;
	T_MFW_BT_DM_AUTH_CMPL	*auth_cmpl_param;

	MFW_BT_TRACE_P1("mmi_bt_pin_req_cntrl() : Event Received : %d", event);

	switch (event)
	{
		case BT_PIN_REQ:
#ifdef NEW_EDITOR
			/*
			** Initialise the editor
			*/
			AUI_edit_SetDefault(&editor_data);
			AUI_edit_SetMode(&editor_data, ED_MODE_HIDDEN, ED_CURSOR_BAR);

			AUI_edit_SetBuffer(&editor_data, ATB_DCS_ASCII, data->bt_pin_req_buf, MFW_BT_MAX_PIN_CODE_LEN);
			AUI_edit_SetTextStr(&editor_data, TxtSoftSelect, TxtSoftBack, TxtBtEnterPassKey, TxtNull);
			AUI_edit_SetAltTextStr(&editor_data, 1, TxtNull, TRUE, TxtCancel);
			

			AUI_edit_SetEvents(&editor_data, BT_PIN_REQ_EDITOR, TRUE, FOREVER, (T_AUI_EDIT_CB)mmi_bluetooth_editor_cb);

			pin_req_param = (T_MFW_BT_DM_PIN_REQ *)parameter;
			memcpy(&data->bt_pin_req_dev, &pin_req_param->bd_addr, sizeof(T_MFW_BT_DM_DEV_ADDR));
			data->bt_pin_req_editor = AUI_edit_Start(data->win, &editor_data);
#endif
			break;

		case BT_AUTH_COMPLETE:
			auth_cmpl_param = (T_MFW_BT_DM_AUTH_CMPL *)parameter;

			if (memcmp(auth_cmpl_param->bd_addr, data->bt_pin_req_dev, sizeof(T_MFW_BT_DM_DEV_ADDR)) != 0)
			{
				MFW_BT_TRACE("mmi_bt_pin_req_cntrl() > AUTH Complete event with invalid BD Address");
				return;
			}

			if (data->bt_please_wait_dialog != (void *)0)
			{
				SEND_EVENT(data->bt_please_wait_dialog, DIALOG_DESTROY, 0, 0);

				data->bt_please_wait_dialog = (void *)0;
			}

			if (data->bt_pin_req_editor != (void *)0)
			{
				/*
				** Destory the current Pin Entry Window, as Bluetooth has timed out the request
				*/
				AUI_edit_Destroy(data->bt_pin_req_editor);

				data->bt_pin_req_editor = (void *)0;
				memset(data->bt_pin_req_buf, 0x00, MFW_BT_MAX_PIN_CODE_LEN+1);

				/*
				** Create a timed dialog to display the Message "Failed"
				*/
				mmi_bluetooth_show_info(0, TxtBtPassKey, TxtBtTimeout);
			}
			else if (data->bt_required_response == BT_SUCCESS_FAIL_RESP)
			{
				if (auth_cmpl_param->is_success == FALSE)
				{
						/*
						** Create a timed dialog to display the Message "Failed"
						*/
						mmi_bluetooth_show_info(0, TxtFailed, TxtNull);
				}
				else
				{
					/*
					** Create a timed dialog to display the Message "Pin OK"
					*/
					mmi_bluetooth_show_info(0, TxtPINOK, TxtNull);
				}
			}

			/*
			** Destory the PIN Request Window, the editor has been destroyed and the last response received.
			*/
			mmi_bt_pin_request_destroy(data->win);
			break;


		case BT_EDITOR_CANCEL:

			data->bt_required_response = BT_NO_RESP;

			if (value == BT_PIN_REQ_EDITOR)
			{
				/*
				** The User has cancelled the input from a Pin request,
				** return a FALSE value to the MFW as an indication. Not bothered about the
				** return value as this is a fail anyway!
				*/
				(void)mfw_bt_dm_pin_code((void *)0, 0);

				/*
				** The editor will have been destroyed. Reset the Window handler
				*/
				data->bt_pin_req_editor = (void *)0;
			}
			else
				MFW_BT_TRACE_P1("mmi_bt_pin_req_cntrl(), BT_EDITOR_CANCEL event received with unexpected value %d", value);

			break;

		case BT_EDITOR_SELECT:
			if (value == BT_PIN_REQ_EDITOR)
			{
				data->bt_required_response = BT_SUCCESS_FAIL_RESP;
				/*
				** The user has entered a Pin Key, pass it to the MFW for processing
				*/
				btRetVal = mfw_bt_dm_pin_code((void *)&data->bt_pin_req_buf, strlen((void *)&data->bt_pin_req_buf));

				/*
				** CQ21957 : The editor will have been destroyed. Reset the Window handler
				*/
				data->bt_pin_req_editor = (void *)0;

				if (btRetVal != MFW_BT_SUCCESS)
				{
					MFW_BT_TRACE_P1("mmi_bt_pin_req_cntrl() : Attempt to set return Pin Code Failed with %d", btRetVal);
				}
				else
					data->bt_please_wait_dialog = mmi_bluetooth_show_please_wait(data->win);
			}
			else
			{
				MFW_BT_TRACE_P1("mmi_bt_pin_req_cntrl(), BT_EDITOR_SELECT event received with unexpected value %d", value);
			}
			break;

		default:
			MFW_BT_TRACE("mmi_bt_pin_req_cntrl() : Unexpected Event!");
	}

	return;
}

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

 $Function:		mmi_bt_dev_name_create

 $Description:		This function performs the necessary steps to create the a window to handle the
 				Device Name Request. It will be removed, or rather remove itself on returning the
 				data to the Mfw.
 				
 $Returns:		T_MFW_HND : Window Handle to the New Window, Null if failed.

 $Arguments:		parent : pointer to the parent window.

*******************************************************************************/
T_MFW_HND mmi_bt_dev_name_create(T_MFW_HND parent)
{
	T_MMI_BT_Dev_Name_Data *data;
	T_MFW_WIN * win;

	data = (T_MMI_BT_Dev_Name_Data *)mfwAlloc((U16)sizeof(T_MMI_BT_Dev_Name_Data));

	if (data == (void *)0)
		return data;

	data->win = winCreate(parent, 0, E_WIN_VISIBLE, mmi_bluetooth_win_cb);

	if (data->win == (void *)0)
	{
		/*
		** Failed to start : Free Memory, and exit
		*/
		mfwFree((U8 *)data, (U16)sizeof(T_MMI_BT_Dev_Name_Data));
		data = (void *)0;
		return data;
	}
	else
	{
		/*
		** Setup the Dialog control functions
		*/
		data->mmi_control.dialog = (T_DIALOG_FUNC)mmi_bt_dev_name_cntrl;
		data->mmi_control.data = data;
		
		win = ((T_MFW_HDR *)data->win)->data;
		win->user = (void *)data;
	}

	bt_data.bt_dev_name_win = data->win;
	return data->win;

}

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

 $Function:		mmi_bt_dev_name_destroy

 $Description:		This function performs the necessary steps to remove the window handling the
 				Device Name request, tidying up all allocated resources.

 $Returns:		MfwResOk : Success
 				MfwResIllHnd : Illegal Window Handler provided

 $Arguments:		win : Window to be destroyed

*******************************************************************************/
MfwRes mmi_bt_dev_name_destroy(T_MFW_HND win)
{
	T_MFW_WIN * win_data;
	T_MMI_BT_Dev_Name_Data * data;

	if (win == (void *)0)
		return MfwResIllHnd;

	win_data = ((T_MFW_HDR *) win)->data;
	data = (T_MMI_BT_Dev_Name_Data *)win_data->user;

	/*
	** Destroy the Window
	*/
	win_delete(data->win);

	/*
	** Free the dynamically allocated memory
	*/
	mfwFree((U8 *)data, (U16)sizeof(T_MMI_BT_Dev_Name_Data));

	bt_data.bt_dev_name_win = (void *)0;
	return MfwResOk;
}


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

 $Function:		mmi_bt_dev_name_cntrl

 $Description:		This is the dialog control function for the Device Name Request Window. It
 				receives the signals from the MFW and determines what action, if any, to take.

 $Returns:		None

 $Arguments:		win :		The pointer to the window handler, so the function can reference the
							dynamic user data, if any.
 				event :		The incoming event
 				value :		Generic incoming Parameter, it will be 'event' dependant
 				parameter :	Generic incoming Parameter, it will be 'event' dependant

*******************************************************************************/
void mmi_bt_dev_name_cntrl (T_MFW_HND win, USHORT event, SHORT value, void * parameter)
{
	T_MFW_WIN			* win_data = ((T_MFW_HDR *) win)->data;
	T_MMI_BT_Dev_Name_Data * data = (T_MMI_BT_Dev_Name_Data *)win_data->user;

	T_AUI_EDITOR_DATA	editor_data;
	UBYTE				*ptr_device_name;

	T_MFW_BT_STATUS		btRetVal;
	
	MFW_BT_TRACE_P1("mmi_bt_dev_name_cntrl() : Event Received : %d", event);

	switch (event)
	{
		case BT_DEV_NAME_REQ:
#ifdef NEW_EDITOR
			/*
			** Get the current Device Name from the MFW
			*/
			ptr_device_name = mfw_bt_dm_get_local_name();

			memcpy(&data->bt_device_name, ptr_device_name, MFW_BT_NAME_LENGTH);

			/*
			** Initialise the editor
			*/
			AUI_edit_SetDefault(&editor_data);

			AUI_edit_SetBuffer(&editor_data, ATB_DCS_ASCII, data->bt_device_name, MFW_BT_NAME_LENGTH);
			AUI_edit_SetTextStr(&editor_data, TxtSoftSelect, TxtSoftBack, TxtBtEnterDeviceName, TxtNull);
			AUI_edit_SetAltTextStr(&editor_data, 1, TxtNull, TRUE, TxtCancel);

			AUI_edit_SetEvents(&editor_data, BT_DEV_NAME_EDITOR, TRUE, FOREVER, (T_AUI_EDIT_CB)mmi_bluetooth_editor_cb);

			data->bt_dev_name_editor = AUI_edit_Start(data->win, &editor_data);
#endif
			break;

		case BT_SET_REM_DEV_NAME:		/* CQ21843 : Get a Friendly name for a remote device */
#ifdef NEW_EDITOR
			data->rem_device_info = (T_MFW_BT_REM_DEVICE_INFO *)parameter;

			memcpy(&data->bt_dev_address, &data->rem_device_info->bd_addr, sizeof(T_MFW_BT_DM_DEV_ADDR));
			memcpy(&data->bt_device_name, data->rem_device_info->name, MFW_BT_NAME_LENGTH);

			/*
			** Initialise the editor
			*/
			AUI_edit_SetDefault(&editor_data);

			AUI_edit_SetBuffer(&editor_data, ATB_DCS_ASCII, data->bt_device_name, MFW_BT_NAME_LENGTH);
			AUI_edit_SetTextStr(&editor_data, TxtSoftSelect, TxtSoftBack, TxtBtEnterDeviceName, TxtNull);
			AUI_edit_SetAltTextStr(&editor_data, 1, TxtNull, TRUE, TxtCancel);

			AUI_edit_SetEvents(&editor_data, BT_REM_DEV_NAME_EDITOR, TRUE, FOREVER, (T_AUI_EDIT_CB)mmi_bluetooth_editor_cb);

			data->bt_dev_name_editor = AUI_edit_Start(data->win, &editor_data);
#endif
			break;

		case BT_EDITOR_CANCEL:

			if (value == BT_DEV_NAME_EDITOR)
			{
				if (bt_data.bt_DevNameForStartup)
				{
					/*
					** The User has cancelled the input from a "Device Name" request, which was
					** requested as a result of the startup sequence. Return a FALSE value to the
					** MFW as an indication. Not bothered about the return value as this is a fail anyway!
					*/
					(void)mfw_bt_dm_set_local_name((void *)0);
				}

				/*
				** The editor will have been destroyed. Reset the Window handler
				*/
				data->bt_dev_name_editor = (void *)0;
			}
			else if (value == BT_REM_DEV_NAME_EDITOR)	/* CQ21843 : Add Editor processing for new action */
			{
				/*
				** The editor will have been destroyed. Reset the Window handler
				*/
				data->bt_dev_name_editor = (void *)0;
			}
			else
			{
				MFW_BT_TRACE_P1("mmi_bt_dev_name_cntrl(), BT_EDITOR_CANCEL event received with unexpected value %d", value);
			}

			/*
			** Destroy the Device Name Request Window
			*/
			mmi_bt_dev_name_destroy(data->win);
			break;

		case BT_EDITOR_SELECT:
			if (value == BT_DEV_NAME_EDITOR)
			{
				/*
				** The user has entered a Device Name, pass it to the MFW for processing
				*/
				btRetVal = mfw_bt_dm_set_local_name((void *)&data->bt_device_name);

				if (btRetVal != MFW_BT_SUCCESS)
				{
					MFW_BT_TRACE_P1("mmi_bt_dev_name_cntrl() : Attempt to set Device Name Failed with %d", btRetVal);
				}
				else
				{
					/*
					** Create a timed dialog to display the Message "Device Name Set"
					*/
					mmi_bluetooth_show_info(0, TxtBtDeviceName, TxtBtSet);
				}

				/*
				** CQ21957 : The editor will have been destroyed. Reset the Window handler
				*/
				data->bt_dev_name_editor = (void *)0;
			}
			else if (value == BT_REM_DEV_NAME_EDITOR)	/* CQ21843 : Add Editor processing for new action */
			{
				/*
				** The user has entered a Device Name, pass it to the MFW for processing
				*/
				btRetVal = mfw_bt_dm_rename_device(data->bt_dev_address, data->bt_device_name);

				if (btRetVal != MFW_BT_SUCCESS)
				{
					MFW_BT_TRACE_P1("mmi_bt_dev_name_cntrl() : Attempt to set Remote Device Name Failed with %d", btRetVal);
				}
				else
				{
					/*
					** Create a timed dialog to display the Message "Device Name Set"
					*/
					mmi_bluetooth_show_info(0, TxtBtDeviceName, TxtBtSet);

					/*
					** Set the Name in the local Device list, so that the Menu will be updated
					*/
					memcpy(&data->rem_device_info->name, &data->bt_device_name, MFW_BT_NAME_LENGTH);
				}

				/*
				** CQ21957 : The editor will have been destroyed. Reset the Window handler
				*/
				data->bt_dev_name_editor = (void *)0;
			}
			else
			{
				MFW_BT_TRACE_P1("mmi_bt_dev_name_cntrl(), BT_EDITOR_SELECT event received with unexpected value %d", value);
			}

			/*
			** Destroy the Device Name Request Window
			*/
			mmi_bt_dev_name_destroy(data->win);
			break;

		default:
			MFW_BT_TRACE("mmi_bt_dev_name_cntrl() : Unexpected Event!");
	}

	return;
}

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

 $Function:		mmi_bt_authorize_create

 $Description:		This function performs the necessary steps to create the a window to handle the
 				Authorize Request. It will be removed, or rather remove itself on returning the
 				data to the Mfw.
 
 $Returns:		T_MFW_HND : Window Handle to the New Window, Null if failed.

 $Arguments:		parent : pointer to the parent window.

*******************************************************************************/
T_MFW_HND mmi_bt_authorize_create(T_MFW_HND parent)
{
	T_MMI_BT_Authorise_Data *data;
	T_MFW_WIN * win;

	data = (T_MMI_BT_Authorise_Data *)mfwAlloc((U16)sizeof(T_MMI_BT_Authorise_Data));

	if (data == (void *)0)
		return data;

	data->win = winCreate(parent, 0, E_WIN_VISIBLE, mmi_bluetooth_win_cb);

	if (data->win == (void *)0)
	{
		/*
		** Failed to start : Free Memory, and exit
		*/
		mfwFree((U8 *)data, (U16)sizeof(T_MMI_BT_Authorise_Data));
		data = (void *)0;
		return data;
	}
	else
	{
		/*
		** Setup the Dialog control functions
		*/
		data->mmi_control.dialog = (T_DIALOG_FUNC)mmi_bt_authorize_cntrl;
		data->mmi_control.data = data;
		
		win = ((T_MFW_HDR *)data->win)->data;
		win->user = (void *)data;
	}

	bt_data.bt_authorize_win = data->win;
	return data->win;

}

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

 $Function:		mmi_bt_authorize_destroy

 $Description:		This function performs the necessary steps to remove the window handling for the
 				Authorize request, tidying up all allocated resources.

 $Returns:		MfwResOk : Success
 				MfwResIllHnd : Illegal Window Handler provided

 $Arguments:		win : Window to be destroyed

*******************************************************************************/
MfwRes mmi_bt_authorize_destroy(T_MFW_HND win)
{
	T_MFW_WIN * win_data;
	T_MMI_BT_Authorise_Data * data;

	if (win == (void *)0)
		return MfwResIllHnd;

	win_data = ((T_MFW_HDR *) win)->data;
	data = (T_MMI_BT_Authorise_Data *)win_data->user;

	/*
	** Destroy the Window
	*/
	win_delete(data->win);

	/*
	** Free the dynamically allocated memory
	*/
	mfwFree((U8 *)data, (U16)sizeof(T_MMI_BT_Authorise_Data));

	bt_data.bt_authorize_win = (void *)0;
	return MfwResOk;
}


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

 $Function:		mmi_bt_authorize_cntrl

 $Description:		This is the dialog control function for the Authorise Request Window. It receives
 				the signals from the MFW and determines what action, if any, to take.

 $Returns:		None

 $Arguments:		win :		The pointer to the window handler, so the function can reference the
							dynamic user data, if any.
 				event :		The incoming event
 				value :		Generic incoming Parameter, it will be 'event' dependant
 				parameter :	Generic incoming Parameter, it will be 'event' dependant

*******************************************************************************/
void mmi_bt_authorize_cntrl (T_MFW_HND win, USHORT event, SHORT value, void * parameter)
{
	T_MFW_WIN			* win_data = ((T_MFW_HDR *) win)->data;
	T_MMI_BT_Authorise_Data * data = (T_MMI_BT_Authorise_Data *)win_data->user;

	T_DISPLAY_DATA		display_info;

	T_MFW_BT_STATUS		btRetVal;

	MFW_BT_TRACE_P1("mmi_bluetooth() : Event Received : %d", event);

	switch (event)
	{
		case BT_AUTHORIZE_REQ:
			data->bt_auth_req_param = (T_MFW_BT_DM_AUTHORIZE_REQ *)mfwAlloc(sizeof(T_MFW_BT_DM_AUTHORIZE_REQ));

			if (data->bt_auth_req_param == (T_MFW_BT_DM_AUTHORIZE_REQ *)0)
			{
				/*
				** Problems with Memory Allocation, so reject the request this time
				*/
				btRetVal = mfw_bt_dm_authorize_resp(MFW_BT_AUTH_FAIL);
				mfwFree((void *)data->bt_auth_req_param, (U16)sizeof(T_MFW_BT_DM_AUTHORIZE_REQ));
				mmi_bt_authorize_destroy(data->win);
				return;
			}

			memcpy(data->bt_auth_req_param, parameter, sizeof(T_MFW_BT_DM_AUTHORIZE_REQ));

			/*
			** if the length of the Device Name is greater than a predefined limit, truncate it :o)
			*/
			if (strlen((char *)(data->bt_auth_req_param)->bd_name) > BT_MAX_DISPLAY_DEV_NAME_LENGTH)
			{
				/*
				** Terminate the device name at this maximum length!
				** It will be used for display purposes only!
				*/
				data->bt_auth_req_param->bd_name[BT_MAX_DISPLAY_DEV_NAME_LENGTH] = 0x00;
			}

			/*
			** Create a popup dialog to prompt the user whether to proceed with the authorization.
			** CQ22022 : Call to dlg_initDisplayData_TextId removed, and dlg_initDisplayData_TextStr updated.
			*/
			dlg_initDisplayData_TextStr( &display_info, TxtSoftOptions, TxtNo, MmiRsrcGetText(TxtBtAuthorize), (char *)(data->bt_auth_req_param)->bd_name, COLOUR_STATUS);

			dlg_initDisplayData_events(&display_info, (T_VOID_FUNC)mmi_bt_authorize_dlg_cb, BT_AUTHORISE_RESP_TIMEOUT, KEY_HUP | KEY_LEFT| KEY_RIGHT);

			data->bt_auth_info_win = info_dialog(data->win, &display_info);
			break;
		default:
			MFW_BT_TRACE("mmi_bluetooth() : Unexpected Event!");
	}

	return;
}


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

 $Function:		mmi_bt_authorize_dlg_cb

 $Description:		This function is the windows callback function for the Authorize Request Dialog.

 $Returns:		None

 $Arguments:		win : The pointer to the window handler, so the function can reference the
				dynamic user data, if any.
				identifier : is a flag set during Dialog Create.
 				reason : is the event to be processed

*******************************************************************************/
void mmi_bt_authorize_dlg_cb(T_MFW_HND win, UBYTE identifier, UBYTE reason)
{
	T_MFW_HND	parent = bt_data.bt_authorize_win;
	T_MFW_WIN   * win_data = ((T_MFW_HDR *) parent)->data;
	T_MMI_BT_Authorise_Data * data = (T_MMI_BT_Authorise_Data *)win_data->user;
	T_MFW_BT_STATUS	btRetVal;

	MFW_BT_TRACE("mmi_bt_authorize_dlg_cb()");

	switch (reason)	 
	{

		case INFO_KCD_LEFT:
			/*
			** Create an Authorize Menu and get the Response (Once, Always or No)
			*/
			data->bt_auth_menu = bt_menu_start(data->win, (MfwMnuAttr *)&menuBtAuthorize, (T_VOID_FUNC)mmi_bt_authorize_rsk);

			/*
			** CQ22021 : The Dialog is destroyed automatically, reset the win value to NULL
			*/
			data->bt_auth_info_win = 0;
			break;

		case INFO_KCD_HUP:
		case INFO_KCD_RIGHT:
			btRetVal = mfw_bt_dm_authorize_resp((U8)MFW_BT_AUTH_FAIL);
			mfwFree((void *)data->bt_auth_req_param, (U16)sizeof(T_MFW_BT_DM_AUTHORIZE_REQ));

			/*
			** CQ22021 : The Dialog is destroyed automatically, reset the win value to NULL
			*/
			data->bt_auth_info_win = 0;
			mmi_bt_authorize_destroy(data->win);
			break;
	}

	return;
}

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

 $Function:		mmi_bluetooth_search_create

 $Description:		This function performs the necessary steps to create the bluetooth search window,
 				set up the dialog, and create a Bluetooth Entity within that window. The Bt Search window
 				is a child of the Bt Root Window, and is used to manage the search for local devices or
 				the listing of known devices and the subsequent functions available after that
 
 $Returns:		BOOL - True is successful, otherwise FALSE

 $Arguments:		None

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

BOOL mmi_bt_search_create (T_MFW_HND parent)
{
	T_MMI_BtSearchData *data = &bt_srch_data;
	T_MFW_WIN		    *win;
	BOOL retVal = TRUE;

	MFW_BT_TRACE("mmi_bt_search_create()");

	/*
	** If the Bluetooth Search is already created then there is nothing to do.
	*/
	if ((data->win == (void *)0) ||
	     (data->srch_bt_cmpnt == (void *)0))
	{
		/*
		** Create the Bluetooth Search Window
		*/
		MFW_BT_TRACE("mmi_bt_search_create >> Creating BT Search Window");
		if (data->win == (void *)0)
			data->win = win_create(parent, 0, E_WIN_VISIBLE, (MfwCb)mmi_bluetooth_win_cb);

		if (data->win == (void *)0)
		{
			MFW_BT_TRACE("mmi_bt_search_create >> Create BT Search Window FAILED");
			/*
			** Bluetooth Search Failed to start
			*/
			retVal = FALSE;
		}
		else
		{
			MFW_BT_TRACE("mmi_bt_search_create >> Configuring Window Dialog");
			/*
			** Setup the Dialog control functions
			*/
			data->srch_bt_control.dialog = (T_DIALOG_FUNC)mmi_bt_search_cntrl;
			data->srch_bt_control.data = data;
			
			win = ((T_MFW_HDR *)data->win)->data;
			win->user = (void *)data;

			/*
			** Create a Bluetooth component
			*/
			if (data->srch_bt_cmpnt == (void *)0)
			{
				MFW_BT_TRACE("mmi_bt_search_create >> Creating MFW_BT Component");
				data->srch_bt_cmpnt = mfw_bt_create(data->win, E_BT_ALL_SERVICES, (MfwCb)mmi_bluetooth_search_cb);
			}
			else
			{
				MFW_BT_TRACE("mmi_bt_search_create >> MFW_BT Component Already EXISTS????");
			}

			if (data->srch_bt_cmpnt == (void *)0)
			{
				retVal = FALSE;
				/*
				** Bluetooth Search Compnonent Failed to start
				*/
				winDelete(data->win);
			}
			else
			{
				/*
				** Create a Timer component to Timeout a Device Search if no response from BT_Mobile
				*/
				MFW_BT_TRACE("mmi_bt_search_create > Creating the search timer");
				if (data->srch_bt_search_timer == (void *)0)
					data->srch_bt_search_timer = timCreate(data->win,
														BT_SEARCH_RESP_TIMEOUT,
														(MfwCb)mmi_bluetooth_search_timer_cb);

				if (data->srch_bt_search_timer == (void *)0)
				{
					MFW_BT_TRACE("mmi_bt_search_create > search timer creation failed ");
					/*
					** Timer Compnonent Failed to start, delete previous components
					*/
					mfw_bt_delete(data->srch_bt_cmpnt);
					winDelete(data->win);
				}
				else
				{
					timStart(data->srch_bt_search_timer);
				}
			}
		}
	}

	return retVal;
	
}


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

 $Function:		mmi_bluetooth_destroy

 $Description:		This function performs the necessary steps to remove the bluetooth, search window
   				tidying up all allocated resources.

 $Returns:		None

 $Arguments:		None

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

GLOBAL void  mmi_bt_search_destroy (void)
{
	T_MMI_BtSearchData * data = &bt_srch_data;

	MFW_BT_TRACE("mmi_bluetooth_search_destroy()");

	if (data->win == (void *)0)
		return;

	if (data->srch_bt_pairing_pin_editor != (void *)0)
		SEND_EVENT(data->srch_bt_pairing_pin_editor, E_ED_DEINIT, 0, 0);

	if (data->srch_bt_please_wait_dialog != (void *)0)
		SEND_EVENT(data->srch_bt_please_wait_dialog, DIALOG_DESTROY, 0, 0);

	if (data->srch_bt_cmpnt != (void *)0)
		mfw_bt_delete(data->srch_bt_cmpnt);

	if (data->srch_bt_search_timer != (void *)0)
		timDelete(data->srch_bt_search_timer);
	winDelete(data->win);

	data->win = (void *)0;
	data->srch_bt_pairing_pin_editor = (void *)0;
	data->srch_bt_please_wait_dialog = (void *)0;
	data->srch_bt_dev_list_win = (void *)0;
	data->srch_bt_show_services_win = (void *)0;
	data->srch_bt_cmpnt = (void *)0;
	data->srch_bt_search_timer = (void *)0;
	

	return;
}


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

 $Function:		mmi_bt_search_cntrl

 $Description:		This is the dialog control function for the Bluetooth Search Window. It receives the signals
 				from the MFW or BMI and determines what action, if any, to take.

 $Returns:		None

 $Arguments:		win :		The pointer to the window handler, so the function can reference the
							dynamic user data, if any.
 				event :		The incoming event
 				value :		Generic incoming Parameter, it will be 'event' dependant
 				parameter :	Generic incoming Parameter, it will be 'event' dependant

*******************************************************************************/
void mmi_bt_search_cntrl (T_MFW_HND win, USHORT event, SHORT value, void * parameter)
{
	T_MFW_WIN			* win_data = ((T_MFW_HDR *) win)->data;
	T_MMI_BtSearchData	* data = (T_MMI_BtSearchData *)win_data->user;

	T_DISPLAY_DATA		display_info;
	T_AUI_EDITOR_DATA	editor_data;
	BOOL				valid;
	BOOL				btIsDiscoverable;
	UBYTE				*ptr_device_name;

	T_MFW_BT_STATUS			btRetVal;
	
	T_MFW_BT_DM_AUTH_CMPL		*auth_cmpl_param;
	T_MFW_BT_DM_INQ_CMPL		*inq_cmpl_param;
	T_MFW_BT_DM_DISC_RES		*disc_res_param;
	T_MFW_BT_REM_DEVICE_INFO	*cur_device;

	MfwMnuItem *listItem;
	T_MFW_BT_REM_DEVICE_INFO *device;
	MfwMnuItem			*ptr_tempListItem;
	T_MFW_BT_REM_DEVICE_INFO	*ptr_tempDevDb;
	UINT8 num_of_services;


	int  iLoop;
	
	MFW_BT_TRACE_P1("mmi_bt_search_cntrl() : Event Received : %d", event);

	switch (event)
	{
		case BT_EDITOR_CANCEL:

			if ((value == BT_DEV_NAME_EDITOR) ||
			     (value == BT_REM_DEV_NAME_EDITOR) ||		/* CQ21843 : Editor Identier has another value */
			     (value == BT_PIN_REQ_EDITOR))
			{
				/*
				** Not handled by this window, pass to the root window.
				*/
				MFW_BT_TRACE_P1("mmi_bt_search_cntrl() : Unexpected Editor Cancel Event : value = %d!", value);
			}
			else if (value == BT_PAIRING_EDITOR)
			{
				data->srch_bt_req_resp = BT_NOT_EXPECTED;

				/*
				** The User has cancelled the input from a Pairing  Pin request,
				** the process has not been started. Don't proceed.
				*/
				/*
				** The editor will have been destroyed. Reset the Window handler
				*/
				data->srch_bt_pairing_pin_editor = (void *)0;
			}
			else
			{
				MFW_BT_TRACE_P1("mmi_bt_search_cntrl(), BT_EDITOR_CANCEL event received with unknown value %d", value);
			}

			break;

		case BT_EDITOR_SELECT:
			if ((value == BT_DEV_NAME_EDITOR) ||
			     (value == BT_REM_DEV_NAME_EDITOR) ||		/* CQ21843 : Editor Identier has another value */
			     (value == BT_PIN_REQ_EDITOR))
			{
				/*
				** Not handled by this window, pass to the root window.
				*/
				MFW_BT_TRACE_P1("mmi_bt_search_cntrl() : Unexpected Editor Select Event : value = %d!", value);
			}
			else if (value == BT_PAIRING_EDITOR)
			{
				/*
				** The editor will have been destroyed. Reset the Window handler
				*/
				data->srch_bt_pairing_pin_editor = (void *)0;

				data->srch_bt_req_resp = BT_PAIRED_NOT_RESP;

				/*
				**The user has entered a Pin Key, now use it in the pairing process
				*/
				cur_device = &data->srch_bt_dev_list[data->srch_bt_cur_dev_idx];

				btRetVal = mfw_bt_dm_bond(cur_device->bd_addr,
										     (void *)&data->bt_pairing_pin_buf,
										     strlen((void *)&data->bt_pairing_pin_buf));

				if (btRetVal != MFW_BT_SUCCESS)
				{
					MFW_BT_TRACE_P1("mmi_bt_search_cntrl() : Attempt to start Pairing process Failed with %d", btRetVal);
				}
				else
					data->srch_bt_please_wait_dialog = mmi_bluetooth_show_please_wait(data->win);
			}
			else
			{
				MFW_BT_TRACE_P1("mmi_bt_search_cntrl(), BT_EDITOR_SELECT event received with unknown value %d", value);
			}

			break;

		case BT_AUTH_COMPLETE:
			auth_cmpl_param = (T_MFW_BT_DM_AUTH_CMPL *)parameter;

			if (data->srch_bt_req_resp == BT_NOT_EXPECTED)
			{
				/*
				** Not handled by this window, pass to the root window.
				*/
				MFW_BT_TRACE("mmi_bt_search_cntrl() : Unexpected Auth_Complete Event");
			}
			else
			{
				UBYTE iLoop;
				T_MFW_BT_REM_DEVICE_INFO *device;

				MFW_BT_TRACE_P6("mmi_bt_search_cntrl(), Auth BD_ADDR 0x%02x%02x%02x%02x%02x%02x",
								     auth_cmpl_param->bd_addr[0], auth_cmpl_param->bd_addr[1],
 								     auth_cmpl_param->bd_addr[2], auth_cmpl_param->bd_addr[3],
								     auth_cmpl_param->bd_addr[4], auth_cmpl_param->bd_addr[5]);
				if (data->srch_bt_please_wait_dialog != (void *)0)
				{
					SEND_EVENT(data->srch_bt_please_wait_dialog, DIALOG_DESTROY, 0, 0);
					data->srch_bt_please_wait_dialog = (void *)0;
				}

				if (data->srch_bt_req_resp == BT_PAIRED_NOT_RESP)
				{
					if (auth_cmpl_param->is_success == FALSE)
					{
						/*
						** Create a timed dialog to display the Message "Pairing Failed"
						*/
						mmi_bluetooth_show_info(data->win, TxtBtPairing, TxtFailed);
					}
					else
					{
						/*
						** Create a timed dialog to display the Message "Paired"
						*/
						mmi_bluetooth_show_info(data->win, TxtBtPaired, TxtNull);

						/*
						** This will have been as part of a "Device List" either known or local
						** The device will have been added to the known devices list, and will
						** have a link_key present. Update our local data to reflect this.
						*/
						iLoop = 0;
						while (iLoop < data->srch_bt_num_devices)
						{
							device = &data->srch_bt_dev_list[iLoop];

							MFW_BT_TRACE_P7("mmi_bt_search_cntrl(), dev_list[%d] BD_ADDR 0x%02x%02x%02x%02x%02x%02x",
											     iLoop, device->bd_addr[0], device->bd_addr[1], device->bd_addr[2], device->bd_addr[3],
											     device->bd_addr[4], device->bd_addr[5]);

							if (memcmp(&device->bd_addr[0], &auth_cmpl_param->bd_addr[0], BD_ADDR_LEN) == 0 )
							{
								MFW_BT_TRACE("mmi_bt_search_cntrl() : Auth_Complete Event, device found");
								device->link_key_present = TRUE;
								device->is_new = FALSE;
								iLoop = 0xFF;
							}
							else
								iLoop++;
						}
					}
				}

				data->srch_bt_req_resp = BT_NOT_EXPECTED;
			}
			break;

		case BT_LIST_KNOWN_DEVICES:
			{
				BD_ADDR null_bd_addr;

				memset(&null_bd_addr, 0x00, sizeof(BD_ADDR));
			/*
			** Get the known devices from the MFW
			*/
			data->srch_bt_mode = BT_MODE_KNOWN_DEVICES;
			
				mfw_bt_dm_get_known_devices(null_bd_addr, BTA_ALL_SERVICE_MASK);
			}
			break;
			
		case BT_DEVICE_SEARCH:
			/*
			** Trigger Bluetooth to search locally for any devices
			*/
			data->srch_bt_mode = BT_MODE_LOCAL_SEARCH;

			/* Search for all devices, not service specified */
			mfw_bt_dm_search(0);
			data->srch_bt_please_wait_dialog = mmi_bluetooth_show_please_wait(data->win);
			break;

		case BT_INQUIRY_COMPLETE:
			MFW_BT_TRACE("mmi_bt_search_cntrl > Recieved the INQUIRY COMPLETE Event");
	
			inq_cmpl_param = (T_MFW_BT_DM_INQ_CMPL *)parameter;

			if ((data->srch_bt_mode == BT_MODE_KNOWN_DEVICES) ||
			     (data->srch_bt_mode == BT_MODE_LOCAL_SEARCH))
			{
				(void)timStop(data->srch_bt_search_timer);
				if (data->srch_bt_please_wait_dialog != (void *)0)
				{
					SEND_EVENT(data->srch_bt_please_wait_dialog, DIALOG_DESTROY, 0, 0);
					data->srch_bt_please_wait_dialog = (void *)0;
				}
			if (inq_cmpl_param->num_resps == 0)
			{
				/*
				** Display an Dialog Screen to display "No Devices Found"
				*/
				mmi_bluetooth_show_info_callback(data->win, TxtBtNoDevices, TxtBtFound, mmi_bt_srch_no_device_found_dlg_cb);
					data->srch_bt_mode = BT_MODE_NO_SEARCH;
			}
			else
			{
					MFW_BT_TRACE("mmi_bt_search_cntrl > Initialising the List");
				/*
				** Create the list menu to display the results
				*/
				/* initialization of the dialog data */
				data->srch_bt_list_devices_menu_data.ListPosition   = 1;/* True cursor position in list menu. */
				data->srch_bt_list_devices_menu_data.Font           = 0;
				data->srch_bt_list_devices_menu_data.LeftSoftKey    = TxtNull;
				data->srch_bt_list_devices_menu_data.RightSoftKey   = TxtCancel;
				data->srch_bt_list_devices_menu_data.KeyEvents      = KEY_RIGHT;
				data->srch_bt_list_devices_menu_data.Reason         = 0;
				data->srch_bt_list_devices_menu_data.Strings        = TRUE;
				data->srch_bt_list_devices_menu_data.autoDestroy    = FALSE;
				
				data->srch_bt_list_devices_menu_data.Attr           = (MfwMnuAttr *)&menuBtSearchListAttr;
				data->srch_bt_list_devices_menu_data.Attr->hdrId = TxtSearching;

					/*
					** CQ21834 : Special processing for Known Device List.
					*/
					if (data->srch_bt_mode == BT_MODE_KNOWN_DEVICES)
					{
						/*
						** "Known devices" requires an extra entry, for further details see the comment below
						*/
						data->srch_bt_list_devices_menu_data.Attr->nItems = inq_cmpl_param->num_resps + 1;
						data->srch_bt_list_devices_menu_data.ListLength = inq_cmpl_param->num_resps + 1; /* actual number of entries in list menu.    */
					}
					else
					{
				data->srch_bt_list_devices_menu_data.Attr->nItems = inq_cmpl_param->num_resps;
						data->srch_bt_list_devices_menu_data.ListLength = inq_cmpl_param->num_resps; /* actual number of entries in list menu.    */
					}
						

				data->srch_bt_list_devices_menu_data.List = (MfwMnuItem *)mfwAlloc(data->srch_bt_list_devices_menu_data.ListLength * sizeof (MfwMnuItem));

				if (data->srch_bt_list_devices_menu_data.List != (MfwMnuItem *)0)
				{
					MfwMnuItem *listItem;

					MFW_BT_TRACE("mmi_bt_search_cntrl > List Memory Allocated successfully");
					/*
					** Initialise the memory to 0x00
					*/
					memset(data->srch_bt_list_devices_menu_data.List, 0x00, data->srch_bt_list_devices_menu_data.ListLength * sizeof (MfwMnuItem));

					for (iLoop = 0; iLoop <data->srch_bt_list_devices_menu_data.ListLength; iLoop++)
					{
						listItem = &data->srch_bt_list_devices_menu_data.List[iLoop];

						listItem->str = MmiRsrcGetText(TxtPleaseWait);
						listItem->menu =     (MfwMnuAttr *)&menuBtDeviceOptions;
						listItem->func =       (MenuFunc)mmi_bluetooth_device_mnu_cb;
						listItem->flagFunc = (FlagFunc)item_flag_hide;
					}

						/*
						** CQ21834 : If we are displaying a list of known devices, then if ALL the devices
						** are removed from the list, there must be another entry to display otherwise
						** the D-Sample will reset because it will enter an infinite loop. This is overcome
						** by added an extra (an normally hidden) entry which will display "No Devices".
						*/
						if (data->srch_bt_mode == BT_MODE_KNOWN_DEVICES)
						{
							listItem = &data->srch_bt_list_devices_menu_data.List[inq_cmpl_param->num_resps];

							listItem->str = MmiRsrcGetText(TxtBtNoDevices);
							listItem->menu =     (MfwMnuAttr *)0;
							listItem->func =       (MenuFunc)0;
							listItem->flagFunc = (FlagFunc)isDeviceListEmpty;
						}
				}

				data->srch_bt_dev_list_cb = (ListCbFunc)bt_srch_dev_list_searching_cb;
				data->srch_bt_dev_list_win = (void *)0;

				/*
				** Create a dynamic memory pool to store the necessary data for the following menus
				*/
				data->srch_bt_num_devices = inq_cmpl_param->num_resps;
				data->srch_bt_dev_list = (T_MFW_BT_REM_DEVICE_INFO *)mfwAlloc(sizeof(T_MFW_BT_REM_DEVICE_INFO) * data->srch_bt_num_devices);

				data->srch_bt_device_count = 0;
				}
			}
			break;

		case BT_DISCOVER_RESULT:

			disc_res_param = (T_MFW_BT_DM_DISC_RES *)parameter;

			if (!mfw_bt_dm_is_discover())
			{
				/* We get here at the end of inquiry process */
			/*
			** If the mode is 'LIST COMPLETE' at this point it is because the user cancel the search but there
			** were device events queued ... ignore them.
			*/
			if ((data->srch_bt_dev_list) &&
			     (data->srch_bt_list_devices_menu_data.List) &&
			     ((data->srch_bt_mode == BT_MODE_KNOWN_DEVICES) ||
			      (data->srch_bt_mode == BT_MODE_LOCAL_SEARCH)))
			{

				if (data->srch_bt_dev_list_win != (void *)0)
				{
					/*
					** The menu is recreated on each device received because the user may decide to halt
					** the search at any point. For Known devices the menu is created at the end because
					** The reponse for ALL devices is immediate.
					** Delete the Menu window, as it will be recreated at the end of this operation
					*/
					listsDestroy(data->srch_bt_dev_list_win);
				}
				
				listItem = &data->srch_bt_list_devices_menu_data.List[data->srch_bt_device_count];
				device = &data->srch_bt_dev_list[data->srch_bt_device_count];

				memcpy(device, disc_res_param, sizeof(T_MFW_BT_REM_DEVICE_INFO));

				listItem->str = device->name;

					/*
					** CQ21834 : For Known Devices, the device should be hidden in the list if the "Remove Device" menu
					** 			option is selected.
					*/
					if (data->srch_bt_mode == BT_MODE_KNOWN_DEVICES)
						listItem->flagFunc = (FlagFunc)isListDeviceUnknown;
					else
				listItem->flagFunc = (FlagFunc)item_flag_none;

				MFW_BT_TRACE_P3("mmi_bt_search_cntrl > Idx %d : Device Name : %s, Item Str %s",
								    data->srch_bt_device_count,
								    device->name,
								    listItem->str);

				data->srch_bt_device_count++;

				if (data->srch_bt_device_count == data->srch_bt_num_devices)
				{
					data->srch_bt_list_devices_menu_data.Attr->hdrId = TxtBtDevices;

					data->srch_bt_list_devices_menu_data.LeftSoftKey = TxtSoftOptions;
					data->srch_bt_list_devices_menu_data.RightSoftKey = TxtSoftBack;
					data->srch_bt_list_devices_menu_data.KeyEvents      = KEY_CLEAR | KEY_RIGHT | KEY_LEFT | KEY_MNUUP | KEY_MNUDOWN |KEY_HUP;
					data->srch_bt_list_devices_menu_data.autoDestroy = TRUE;
					data->srch_bt_mode = BT_MODE_LIST_COMPLETE;

					data->srch_bt_dev_list_cb = (ListCbFunc)bt_srch_dev_list_listmnu_cb;
				}

				if ((data->srch_bt_mode == BT_MODE_LOCAL_SEARCH) ||
				     (data->srch_bt_mode == BT_MODE_LIST_COMPLETE))
				{
					/*
					** Recreate the menu with the new details;
					*/
					if (listDisplayListMenu(data->win, &data->srch_bt_list_devices_menu_data, data->srch_bt_dev_list_cb, FALSE) != LISTS_FAIL)
						data->srch_bt_dev_list_win = data->srch_bt_list_devices_menu_data.win;
				}
			}
			}
			else
			{
				/* We get here at the end of services discovery process */

				if (data->srch_bt_please_wait_dialog != (void *)0)
				{
					SEND_EVENT(data->srch_bt_please_wait_dialog, DIALOG_DESTROY, 0, 0);
					data->srch_bt_please_wait_dialog = (void *)0;
				}

				device = &data->srch_bt_dev_list[data->srch_bt_cur_dev_idx];

				device->services = disc_res_param->services;

				MFW_BT_TRACE("mmi_bt_search_cntrl > Memset srch_bt_cur_dev_serv_list to 0x00 ... ");

			memset(data->srch_bt_cur_dev_serv_list, 0x00, (sizeof(ULONG)*(BTA_MAX_SERVICE_ID-1)));

				num_of_services = bt_count_dev_services(device->services,
												     data->srch_bt_cur_dev_serv_list);

				MFW_BT_TRACE("mmi_bt_search_cntrl > Initialising the List Data");
				/*
				** Create the list menu to display the results
				*/
				/* initialization of the dialog data */
				data->srch_bt_show_services_menu_data.ListPosition   = 1;/* True cursor position in list menu. */
				data->srch_bt_show_services_menu_data.Font           = 0;
				data->srch_bt_show_services_menu_data.LeftSoftKey    = TxtNull;
				data->srch_bt_show_services_menu_data.RightSoftKey   = TxtSoftBack;
				data->srch_bt_show_services_menu_data.KeyEvents      = KEY_CLEAR | KEY_RIGHT | KEY_MNUUP | KEY_MNUDOWN |KEY_HUP;
				data->srch_bt_show_services_menu_data.Reason         = 0;
				data->srch_bt_show_services_menu_data.Strings        = FALSE;
				data->srch_bt_show_services_menu_data.autoDestroy    = TRUE;
				
				data->srch_bt_show_services_menu_data.Attr           = (MfwMnuAttr *)&menuBtShowServicesListAttr;
				data->srch_bt_show_services_menu_data.Attr->hdrId = TxtBtServices;
				data->srch_bt_show_services_menu_data.Attr->nItems = num_of_services;

				data->srch_bt_show_services_menu_data.ListLength = num_of_services; /* actual number of entries in list menu.    */
				data->srch_bt_show_services_menu_data.List = (MfwMnuItem *)mfwAlloc(data->srch_bt_show_services_menu_data.ListLength * sizeof (MfwMnuItem));

				if (data->srch_bt_show_services_menu_data.List != (MfwMnuItem *)0)
				{
					/*
					** Initialise the memory to 0x00
					*/
					memset(data->srch_bt_show_services_menu_data.List, 0x00, data->srch_bt_show_services_menu_data.ListLength * sizeof (MfwMnuItem));

					for (iLoop = 0; iLoop < data->srch_bt_show_services_menu_data.ListLength; iLoop++)
					{
						listItem = &data->srch_bt_show_services_menu_data.List[iLoop];
						
						listItem->str =(char *)bt_get_TxtId_for_service(data->srch_bt_cur_dev_serv_list[iLoop]);
						listItem->flagFunc = (FlagFunc)item_flag_none;
					}

					MFW_BT_TRACE("mmi_bt_search_cntrl > Displaying the List Menu!");

					if (listDisplayListMenu(data->win, &data->srch_bt_show_services_menu_data, (ListCbFunc)bt_srch_service_list_listmnu_cb, FALSE) != LISTS_FAIL)
							data->srch_bt_show_services_win = data->srch_bt_show_services_menu_data.win;
				}
				else
				{
					mmi_bluetooth_show_info(data->win, TxtFailed, TxtNull);
				}
			}



			break;

		case BT_DISCOVER_COMPLETE:
			/*
			** CQ 21838 : This event signifies the end of the discover process, this event shoulkd not be ignored.
			**
			** If the results for all the expected devices have been received then there will be nothing else to do,
			** otherwise this signal will have to trigger the end of the search. If no device results had been
			** reported, then the "No Devices Found".
			*/
			
			if (!mfw_bt_dm_is_discover())
			{
				if (data->srch_bt_device_count != data->srch_bt_num_devices)
				{
					if (data->srch_bt_device_count == 0)
					{
						/*
						** If No devices have been reported display a dialog
						*/
						mmi_bluetooth_show_info_callback(data->win, TxtBtNoDevices, TxtBtFound, mmi_bt_srch_no_device_found_dlg_cb);

						/*
						** Destroy the memory allocated when the inquiry complete was received
						*/
						mfwFree((U8 *)data->srch_bt_list_devices_menu_data.List,
									   (data->srch_bt_list_devices_menu_data.ListLength * sizeof (MfwMnuItem)));

						mfwFree((U8 *)data->srch_bt_dev_list,
										(sizeof(T_MFW_BT_REM_DEVICE_INFO) * data->srch_bt_num_devices));

						data->srch_bt_num_devices = 0;
						data->srch_bt_mode = BT_MODE_NO_SEARCH;
					}
					else
					{
						/*
						** There are devices which have been reported.
						** Change the mode of the list
						*/
						data->srch_bt_mode = BT_MODE_LIST_COMPLETE;

						/*
						** Destroy the window and recreate it
						*/
						listsDestroy(data->srch_bt_dev_list_win);

						/*
						** Allocate memory to copy the devices already listed, copy the active data,
						** and free the memory set aside for ALL the devices to be listed.
						**
						** This should NOT be possible for the known device list, so there is no need to take account of the
						** "No Devices" list entry
						*/

						ptr_tempListItem = (MfwMnuItem *)mfwAlloc(data->srch_bt_device_count * sizeof(MfwMnuItem));
						if (ptr_tempListItem != (MfwMnuItem *)0)
						{
							/*
							** Copy the list of items
							*/
							memcpy(ptr_tempListItem, data->srch_bt_list_devices_menu_data.List, (data->srch_bt_device_count * sizeof(MfwMnuItem)));

							/*
							** Free the first (and larger) list
							*/
							mfwFree((U8 *)data->srch_bt_list_devices_menu_data.List, (U16)(data->srch_bt_list_devices_menu_data.ListLength * sizeof(MfwMnuItem)));

							data->srch_bt_list_devices_menu_data.List = ptr_tempListItem;
						}

						/*
						** Repeat for the 'Device List'
						*/
						ptr_tempDevDb = (T_MFW_BT_REM_DEVICE_INFO *)mfwAlloc(data->srch_bt_device_count * sizeof(T_MFW_BT_REM_DEVICE_INFO));
						if (ptr_tempDevDb!= (T_MFW_BT_REM_DEVICE_INFO *)0)
						{
							/*
							** Copy the list of devices
							*/
							memcpy(ptr_tempDevDb, data->srch_bt_dev_list, (data->srch_bt_device_count * sizeof(T_MFW_BT_REM_DEVICE_INFO)));

							/*
							** Free the first (and larger) list
							*/
							mfwFree((U8 *)data->srch_bt_dev_list, (U16)(data->srch_bt_num_devices * sizeof(T_MFW_BT_REM_DEVICE_INFO)));

							data->srch_bt_dev_list = ptr_tempDevDb;
			}

						/*
						** Configure some other List parameters
						*/
						data->srch_bt_num_devices = data->srch_bt_device_count;
						data->srch_bt_list_devices_menu_data.ListLength = data->srch_bt_device_count;
						
						data->srch_bt_list_devices_menu_data.Attr->nItems = data->srch_bt_device_count;

						data->srch_bt_list_devices_menu_data.Attr->hdrId = TxtBtDevices;
						data->srch_bt_list_devices_menu_data.LeftSoftKey = TxtSoftOptions;
						data->srch_bt_list_devices_menu_data.RightSoftKey = TxtSoftBack;

						/*
						** CQ21842 : Modify the List Key Events so that it handles all teh keys it requires.
						*/
						data->srch_bt_list_devices_menu_data.KeyEvents      = KEY_CLEAR | KEY_RIGHT | KEY_LEFT | KEY_MNUUP | KEY_MNUDOWN |KEY_HUP;

						data->srch_bt_list_devices_menu_data.autoDestroy = TRUE;

						data->srch_bt_dev_list_cb = (ListCbFunc)bt_srch_dev_list_listmnu_cb;

						/*
						** CQ21841 : For each device in the list, reset the string pointer because it will be pointing to the old device
						** list which has just been freed
						*/
						for (iLoop = 0; iLoop < data->srch_bt_num_devices; iLoop++)
							data->srch_bt_list_devices_menu_data.List[iLoop].str = data->srch_bt_dev_list[iLoop].name;
 
						/*
						** Recreate the menu with the new details;
						*/
						if (listDisplayListMenu(data->win, &data->srch_bt_list_devices_menu_data, data->srch_bt_dev_list_cb, FALSE) != LISTS_FAIL)
							data->srch_bt_dev_list_win = data->srch_bt_list_devices_menu_data.win;
					}
				}					
			}

			break;

		case BT_PAIR_DEVICE:
#ifdef NEW_EDITOR
			/*
			** Initialise the editor
			*/
			AUI_edit_SetDefault(&editor_data);
			AUI_edit_SetMode(&editor_data, ED_MODE_HIDDEN, ED_CURSOR_BAR);

			AUI_edit_SetBuffer(&editor_data, ATB_DCS_ASCII, data->bt_pairing_pin_buf, MFW_BT_MAX_PIN_CODE_LEN);
			AUI_edit_SetTextStr(&editor_data, TxtSoftSelect, TxtSoftBack, TxtBtEnterPassKey, TxtNull);
			AUI_edit_SetAltTextStr(&editor_data, 1, TxtNull, TRUE, TxtCancel);

			AUI_edit_SetEvents(&editor_data, BT_PAIRING_EDITOR, TRUE, FOREVER, (T_AUI_EDIT_CB)mmi_bluetooth_editor_cb);

			data->srch_bt_pairing_pin_editor= AUI_edit_Start(data->win, &editor_data);
#endif
			break;

		case BT_SHOW_DEV_SERVICES:

			cur_device = &data->srch_bt_dev_list[data->srch_bt_cur_dev_idx];

			data->srch_bt_please_wait_dialog = mmi_bluetooth_show_please_wait(data->win);
			
			mfw_bt_dm_discover_device(cur_device->bd_addr);
			
			break;

		case BT_DISABLE_SEARCH:
			mmi_bt_search_destroy();
			break;

		default:
			MFW_BT_TRACE("mmi_bluetooth() : Unexpected Event!");
	}

	return;
}


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

 $Function:		mmi_bluetooth_win_cb

 $Description:		This function is the windows callback function for the Bluetooth Root window.
 				It has no display

 $Returns:		MFW_EVENT_REJECTED : This window does not display anything. The event is rejected
 				so it is passed down the win chain.

 $Arguments:		Not used.

*******************************************************************************/
int mmi_bluetooth_win_cb (MfwEvt evt, MfwHnd win)
{
	MFW_BT_TRACE("mmi_bluetooth_win_cb()");

	return MFW_EVENT_REJECTED;
}

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

 $Function:		mmi_bluetooth_device_mnu_cb

 $Description:		This function is called when the user has a list of devices (either known or local)
 				and they select 1.
 				
 $Returns:		BOOL - True is successful, otherwise FALSE

 $Arguments:		None

*******************************************************************************/
static int  mmi_bluetooth_device_mnu_cb(MfwMnu * mnu, MfwMnuItem * item)
{
	MFW_BT_TRACE("mmi_bluetooth_device_mnu_cb()");

	bt_srch_data.srch_bt_cur_dev_idx = mnu->lCursor[mnu->level];

	/*
	** CQ22023 : Modify the Menu Header to display the name of the Current Device
	*/
	menuBtDeviceOptions.hdrId = (int)bt_srch_data.srch_bt_dev_list[bt_srch_data.srch_bt_cur_dev_idx].name;
}

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

 $Function:		mmi_bluetooth_editor_cb

 $Description:		This function provides the callback functionality to an editor for Bluetooth

 $Returns:		None

 $Arguments:	
 
*******************************************************************************/

static void mmi_bluetooth_editor_cb(T_MFW_HND win, USHORT identifier, SHORT reason)
{
	T_MFW_WIN		* win_data = ((T_MFW_HDR *) win)->data;
	T_MMI_BT_PIN_Req_Data * pin_req_data = (T_MMI_BT_PIN_Req_Data *)win_data->user;
	T_MMI_BT_Dev_Name_Data* dev_name_data = (T_MMI_BT_Dev_Name_Data *)win_data->user;
	T_MMI_BtSearchData *srch_data = (T_MMI_BtSearchData *)win_data->user;

	UBYTE			* editor_buffer = NULL;
	SHORT			max_edit_size = 0;
	T_MFW_HND		editor_win;
	T_MFW_HND		parent;

	MFW_BT_TRACE("mmi_bluetooth_editor_cb()");

	if ((identifier == BT_DEV_NAME_EDITOR) ||
	     (identifier == BT_REM_DEV_NAME_EDITOR))	/* CQ21843 */
	{
		editor_buffer = dev_name_data->bt_device_name;
		max_edit_size = MFW_BT_NAME_LENGTH;
		editor_win = dev_name_data->bt_dev_name_editor;
		parent = dev_name_data->win;
	}
	else if (identifier == BT_PIN_REQ_EDITOR)
	{
		editor_buffer = pin_req_data->bt_pin_req_buf;
		max_edit_size = MFW_BT_MAX_PIN_CODE_LEN;
		editor_win = pin_req_data->bt_pin_req_editor;
		parent = pin_req_data->win;
	}
	else if (identifier == BT_PAIRING_EDITOR)
	{
		editor_buffer = srch_data->bt_pairing_pin_buf;
		max_edit_size = MFW_BT_MAX_PIN_CODE_LEN;
		editor_win = srch_data->srch_bt_pairing_pin_editor;
		parent = srch_data->win;
	}
	else
	{
		MFW_BT_TRACE_P1("mmi_bluetooth_editor_cb() : Unknown Identifier %d", identifier);
		/*
		** if this isn't one of the "recognised" editors leave now!
		*/
		return;
	}

	switch (reason)
	{
		case INFO_KCD_LEFT:
		{	
			/*
			** Construct the required string
			*/

			/*
			** The Editor Attributes for all Bluetooth Editors require ASCII text. Text should not be Unicode
			**
			if (editor_buffer[0] == 0x80 )		// If Unicode (there is no way it should be though!!)
			{	//If empty string, remove 0x80 at beginning
				if (editor_buffer[2]==0x00 &&  editor_buffer[3] == 0x00)
					memset(editor_buffer, 0, max_edit_size);
			}
			*/

			/*
			** If there is no string entered, treat this as if it was a "Cancel"
			*/
			if (editor_buffer[0] == 0x00)
			{
				/*
				** Send a "Cancel" to the Bluetooth window
				*/
				SEND_EVENT(parent, BT_EDITOR_CANCEL, identifier, NULL);
			}
			else
			{
				/*
				** Send a "Select" to the Bluetooth window
				*/
				SEND_EVENT(parent, BT_EDITOR_SELECT, identifier, NULL);
			}
		}
		break;

		case INFO_KCD_RIGHT:
			if (strlen((char *)editor_buffer) == 0)
			{
				/*
				** Send a "Cancel" to the Bluetooth window
				*/
				SEND_EVENT(parent, BT_EDITOR_CANCEL, identifier, NULL);
			}
			break;

		case INFO_KCD_HUP:
			/*
			** Set the buffer to NULLS
			*/
			memset(editor_buffer, 0x00, max_edit_size);


			/*
			** Send a "Cancel" to the Bluetooth window
			*/
			SEND_EVENT(parent, BT_EDITOR_CANCEL, identifier, NULL);
			break;

		default:
			/* otherwise no action to be performed
			*/
			break;
	}
}

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

 $Function:		mmi_bluetooth_search_cb

 $Description:		This function 

 $Returns:		None

 $Arguments:	
 
*******************************************************************************/

static int mmi_bluetooth_search_cb(T_MFW_EVENT evnt, void *para)
{
	MFW_BT_TRACE_P1("mmi_bluetooth_search_cb() : event received %d", evnt);

	switch (evnt)
	{
		case E_BT_DM_AUTH_CMPL:
			if (bt_srch_data.srch_bt_req_resp == BT_PAIRED_NOT_RESP)
				SEND_EVENT(bt_srch_data.win, BT_AUTH_COMPLETE, 0, (void *)para);
			else
				return MFW_EVENT_REJECTED;
			break;

		case E_BT_DM_INQ_CMPL:
			SEND_EVENT(bt_srch_data.win, BT_INQUIRY_COMPLETE, 0, (void *)para);
			break;
			
		case E_BT_DM_DISC_RES:
			SEND_EVENT(bt_srch_data.win, BT_DISCOVER_RESULT, 0, (void *)para);
			break;
			
		case E_BT_DM_DISC_CMPL:
			SEND_EVENT(bt_srch_data.win, BT_DISCOVER_COMPLETE, 0, (void *)para);
			break;

		default:
			return MFW_EVENT_REJECTED;
	}

	return MFW_EVENT_CONSUMED;
}
/*******************************************************************************

 $Function:		mmi_bluetooth_root_cb

 $Description:		This function 

 $Returns:		None

 $Arguments:	
 
*******************************************************************************/

static int mmi_bluetooth_root_cb(T_MFW_EVENT evnt, void* para)
{
	T_MFW_BT_STATUS btRetVal;
	T_MMI_BtData *data = &bt_data;
	T_MFW_HND win = mfw_parent(mfw_header());
	
	MFW_BT_TRACE_P1("mmi_bluetooth_root_cb() : event received %d", evnt);

	switch (evnt)
	{
		case E_BT_ENABLE_CMPL:
			if (((T_MFW_BT_ENABLE_CMPL *)para)->Success == FALSE)
			{
				/*
				** Ensure Flag is Disabled
				*/
				data->bt_isActive = FALSE;

				/*
				** Turn the Bluetooth Icon Off ... Not Done because there is no documentation re icons!!!!!
				**                                             and there is not the time to figure them out from Raw Code!!
				*/

				/*
				** Create a timed dialog to display the Message "Bluetooth Failed"
				*/
				mmi_bluetooth_show_info(0, TxtBluetooth, TxtFailed);
			}
			else
			{
				/*
				** Set Flag to Enabled
				*/
				data->bt_isActive = TRUE;

				/*
				** Turn the Bluetooth Icon On ... Not Done because there is no documentation re icons!!!!!
				**                                             and there is not the time to figure them out from Raw Code!!
				*/

				/*
				** Create a timed dialog to display the Message "Bluetooth Activated"
				*/
				mmi_bluetooth_show_info(0, TxtBluetooth, TxtActivated);
			}
			break;

		case E_BT_DISABLE_CMPL:
			/*
			** Set Flag to Enabled
			*/
			data->bt_isActive = FALSE;

			/*
			** Turn the Bluetooth Icon Off ... Not Done because there is no documentation re icons!!!!!
			**                                             and there is not the time to figure them out from Raw Code!!
			*/

			/*
			** Create a timed dialog to display the Message "Bluetooth DeActivated"
			*/
			mmi_bluetooth_show_info(0, TxtBluetooth, TxtDeActivated);
			break;

		case E_BT_DM_DEV_NAME_REQ:
			if (data->bt_dev_name_win == (void *)0)
			{
				data->bt_DevNameForStartup = TRUE;
				data->bt_dev_name_win = mmi_bt_dev_name_create(win);

				if (data->bt_dev_name_win != (void *)0)
				{
					SEND_EVENT(data->bt_dev_name_win, BT_DEV_NAME_REQ, 0, (void *)para);
				}
				else
				{
					MFW_BT_TRACE("mmi_bluetooth_root_cb() : Unable to create Device Name Win!");

					btRetVal = mfw_bt_dm_set_local_name((void *)0);
					if (btRetVal != MFW_BT_SUCCESS)
					{
						MFW_BT_TRACE("mmi_bluetooth_root_cb() : Unable to return Device Name to Mfw!");
					}
				}
			}
			else
			{
				MFW_BT_TRACE("mmi_bluetooth_root_cb() : Device Name Win already active");
			}
			break;

		case E_BT_DM_LINK_UP:
			if (data->bt_num_active_connections < MFW_BT_MAX_CONSEC_CONNECTIONS)
				data->bt_num_active_connections++;
			else
			{
				MFW_BT_TRACE("mmi_bluetooth_root_cb() : LINK_UP indicated after Max Consecutive connections reached");
			}
			break;

		case E_BT_DM_LINK_DOWN:
			if (data->bt_num_active_connections >= 1)
				data->bt_num_active_connections--;
			else
			{
				MFW_BT_TRACE("mmi_bluetooth_root_cb() : LINK_DOWN indicated when no active connections!");
			}
			break;

		case E_BT_DM_PIN_REQ:
			if (data->bt_pin_req_win  == (void *)0)
			{
				data->bt_pin_req_win = mmi_bt_pin_request_create(win);

				if (data->bt_pin_req_win != (void *)0)
				{
					SEND_EVENT(data->bt_pin_req_win, BT_PIN_REQ, 0, (void *)para);
				}
				else
				{
					MFW_BT_TRACE("mmi_bluetooth_root_cb() : Unable to create PIN Req Win!");

					btRetVal = mfw_bt_dm_pin_code((UINT8 *)0, (UINT8)0);
					if (btRetVal != MFW_BT_SUCCESS)
					{
						MFW_BT_TRACE("mmi_bluetooth_root_cb() : Unable to return PIN to Mfw!");
					}
				}
			}
			else
			{
				MFW_BT_TRACE("mmi_bluetooth_root_cb() : PIN Req Win already active");

				btRetVal = mfw_bt_dm_pin_code((UINT8 *)0, (UINT8)0);
				if (btRetVal != MFW_BT_SUCCESS)
				{
					MFW_BT_TRACE("mmi_bluetooth_root_cb() : Unable to return PIN to Mfw!");
				}
			}
			break;

		case E_BT_DM_AUTH_CMPL:
			if (data->bt_pin_req_win != (void *)0)
			{
				SEND_EVENT(data->bt_pin_req_win, BT_AUTH_COMPLETE, 0, (void *)para);
			}
			else
			{
				MFW_BT_TRACE("mmi_bluetooth_root_cb() : PIN Req Win inactive!");
			}
			break;

		case E_BT_DM_AUTHORIZE_REQ:
			if (data->bt_authorize_win == (void *)0)
			{
				data->bt_authorize_win = mmi_bt_authorize_create(win);

				if (data->bt_authorize_win != (void *)0)
				{
					SEND_EVENT(data->bt_authorize_win, BT_AUTHORIZE_REQ, 0, (void *)para);
				}
				else
				{
					MFW_BT_TRACE("mmi_bluetooth_root_cb() : Unable to create Authorization Req Win!");

					btRetVal = mfw_bt_dm_authorize_resp(MFW_BT_AUTH_FAIL);
					if (btRetVal != MFW_BT_SUCCESS)
					{
						MFW_BT_TRACE("mmi_bluetooth_root_cb() : Unable to return Authorization to Mfw!");
					}
				}
			}
			else
			{
				MFW_BT_TRACE("mmi_bluetooth_root_cb() : Authorization IReq Win already active");

				btRetVal = mfw_bt_dm_authorize_resp(MFW_BT_AUTH_FAIL);
				if (btRetVal != MFW_BT_SUCCESS)
				{
					MFW_BT_TRACE("mmi_bluetooth_root_cb() : Unable to return Authorization to Mfw!");
				}
			}
			break;

		case E_BT_DM_SIG_STRENGTH_IND:
			break;

		case E_BT_DM_INQ_RES:
		case E_BT_DM_INQ_CMPL:
		case E_BT_DM_DISC_RES:
		case E_BT_DM_DISC_CMPL:
		default:
			MFW_BT_TRACE("mmi_bluetooth_root_cb() : Unexpected Event!!");
	}
	return MFW_EVENT_CONSUMED;

}

static int mmi_bluetooth_search_timer_cb(MfwEvt e, MfwTim *t)
{
	T_MMI_BtSearchData *data = &bt_srch_data;

	MFW_BT_TRACE("mmi_bluetooth_search_timer_cb()");

	if (data->srch_bt_please_wait_dialog != (void *)0)
	{
		SEND_EVENT(data->srch_bt_please_wait_dialog, DIALOG_DESTROY, 0, 0);
		data->srch_bt_please_wait_dialog = (void *)0;
	}
	/*
	** Display "No Devices Found" and exit the Search Window
	*/
	mmi_bluetooth_show_info_callback(data->win, TxtBtNoDevices, TxtBtFound, mmi_bt_srch_no_device_found_dlg_cb);

	data->srch_bt_mode = BT_MODE_NO_SEARCH;
}
static int mmi_bluetooth_discovery_timer_cb(MfwEvt e, MfwTim *t)
{
	T_MMI_BtData *data = &bt_data;
	T_MFW_BT_STATUS btRetVal;

	MFW_BT_TRACE("mmi_bluetooth_discovery_timer_cb()");

	/*
	** Make the Device Not Discoverable, (Device Hiddenm but from Temporary Request)
	*/
	btRetVal = mfw_bt_dm_set_visibility(FALSE, TRUE);
	
	if (btRetVal != MFW_BT_SUCCESS)
	{
		MFW_BT_TRACE_P1("mmi_bluetooth_discovery_timer_cb() : Set Visibility (FALSE) failed with status : %d", btRetVal);
	}
	else
	{
		/*
		** Create a timed dialog to display the Message "Device Hidden"
		*/
		mmi_bluetooth_show_info(0, TxtBtDevice, TxtBtHidden);
	}

	if (data->bt_stopBtOnDiscoverableTimeout != FALSE)
	{
	/*
	** If there are currently active connections, start the connection timer, otherwise turn bluetooth off
	*/
	if (data->bt_num_active_connections >= 1)
	{
		timStart(data->bt_connection_timer);
	}
	else if (data->bt_isActive != FALSE)
	{
		/*
		** Disable the Bluetooth module
		*/
		mfw_bt_disable();
		}
	}
}

static int mmi_bluetooth_connection_timer_cb(MfwEvt e, MfwTim *t)
{
	T_MMI_BtData *data = &bt_data;

	MFW_BT_TRACE("mmi_bluetooth_connection_timer_cb()");

	/*
	** If there are currently active connections, start the connection timer, otherwise turn bluetooth off
	*/
	if (data->bt_num_active_connections >= 1)
	{
		timStart(data->bt_connection_timer);
	}
	else if (data->bt_isActive != FALSE)
	{
		/*
		** Disable the Bluetooth module
		*/
		mfw_bt_disable();
	}
}

static void mmi_bluetooth_dlg_cb(void)
{
	MFW_BT_TRACE("mmi_bluetooth_dlg_cb()");

	return;
}

static void mmi_bt_srch_no_device_found_dlg_cb(void)
{
	MFW_BT_TRACE("mmi_bt_srch_no_device_found_dlg_cb()");

	mmi_bt_search_destroy();
	return;
}
static MfwHnd mmi_bluetooth_show_please_wait(T_MFW_HND parent)
{
	T_DISPLAY_DATA display_info;

	MFW_BT_TRACE("mmi_bluetooth_show_please_wait()");

	/*
	** Create a timed dialog to display the Message "Failed"
	*/
	dlg_initDisplayData_TextId( &display_info, TxtNull, TxtNull, TxtPleaseWait, TxtNull, COLOUR_STATUS);
	dlg_initDisplayData_events( &display_info, mmi_bluetooth_dlg_cb, FOREVER, 0);

	return info_dialog(parent, &display_info);
}

static MfwHnd mmi_bluetooth_show_info_callback(T_MFW_HND parent, int str1, int str2, T_VOID_FUNC callback)
{
	T_DISPLAY_DATA display_info;

	MFW_BT_TRACE("mmi_bluetooth_show_info()");


	/*
	** Create a timed dialog to display the Message "Failed"
	*/
	dlg_initDisplayData_TextId( &display_info, TxtNull, TxtNull, str1, str2, COLOUR_STATUS);
	dlg_initDisplayData_events( &display_info, callback, BT_INFO_SCRN_TIMEOUT, KEY_LEFT | KEY_CLEAR | KEY_HUP);

	return info_dialog(parent, &display_info);
}

static MfwHnd mmi_bluetooth_show_info(T_MFW_HND parent, int str1, int str2)
{
	return mmi_bluetooth_show_info_callback(parent, str1, str2, mmi_bluetooth_dlg_cb);
}



T_MFW_HND bt_menu_start(MfwHnd parent, MfwMnuAttr* menuAttr, T_VOID_FUNC cancel_cb)
{
	T_MFW_HND win;
		T_MFW_WIN     *win_data;
		T_bt_menu *data;

	MFW_BT_TRACE("bt_menu_start()");

	win = bt_menu_create (parent);

	if (win NEQ NULL)
	{
		win_data = ((T_MFW_HDR *)win)->data;
		data = (T_bt_menu *)win_data->user;

		data->cancel_cb = cancel_cb;

		SEND_EVENT (win, BT_MNU_INIT, 0, (MfwMnuAttr*) menuAttr);
	}

	return win;
}

static T_MFW_HND bt_menu_create(MfwHnd parent)
{
	T_MFW_WIN     * win_data;
	T_bt_menu *  data = (T_bt_menu *)mfwAlloc(sizeof (T_bt_menu));


	MFW_BT_TRACE ("bt_menu_create()");

	data->win = win_create (parent, 0, E_WIN_VISIBLE, (T_MFW_CB)bt_menu_win_cb);

	if (data->win EQ 0)
	return 0;

	/*
	* Create window handler
	*/
	data->mmi_control.dialog   = (T_DIALOG_FUNC)bt_menu;
	data->mmi_control.data     = data;
	win_data                   = ((T_MFW_HDR *)data->win)->data;
	win_data->user             = (void *)data;

	/*
	** Create the keyboard Handler
	*/
	data->kbd = kbdCreate(data->win,KEY_ALL,(MfwCb)bt_menu_kbd_cb);
	data->kbd_long = kbdCreate(data->win,KEY_ALL|KEY_LONG,(MfwCb)bt_menu_kbd_long_cb);

	/*
	* return window handle
	*/
	return data->win;
}

static void bt_menu_destroy(MfwHnd window)
{
	T_MFW_WIN     * win_data  = ((T_MFW_HDR *)window)->data;
	T_bt_menu * data = (T_bt_menu *)win_data->user;

	MfwHnd auth_win = bt_data.bt_authorize_win;
	T_MFW_WIN		* auth_win_data = ((T_MFW_HDR *) auth_win)->data;
	T_MMI_BT_Authorise_Data * auth_data = (T_MMI_BT_Authorise_Data *)auth_win_data->user;

	MFW_BT_TRACE ("bt_menu_destroy()");

	if (window == NULL)
	{
		MFW_BT_TRACE ("Error : Called with NULL Pointer");
		return;
	}

	if (data)
	{
		auth_data->bt_auth_menu = 0;
		winDelete (data->win);
		
		/*
		** Free Memory
		*/
		mfwFree((void *)data, sizeof (T_bt_menu));
	}
}

static void bt_menu (T_MFW_HND win, USHORT event, SHORT value, void * parameter)
{
	T_MFW_WIN      * win_data = ((T_MFW_HDR *) win)->data;
	T_bt_menu      * data = (T_bt_menu *)win_data->user;

	MFW_BT_TRACE ("bt_menu()");

	switch (event)
	{
		case BT_MNU_INIT:
			data->menu = mnuCreate(data->win, (MfwMnuAttr*)parameter, E_MNU_ESCAPE, (MfwCb)bt_menu_mnu_cb);
			mnuLang(data->menu, mainMmiLng);
			mnuUnhide(data->menu);
			winShow(data->win);
			break;

		default:
			return;
	}
}

static int bt_menu_mnu_cb (MfwEvt e, MfwMnu *m)
{
	T_MFW_HND	win  = mfwParent(mfw_header());
	
	MfwHnd auth_win = bt_data.bt_authorize_win;
	T_MFW_WIN		* win_data = ((T_MFW_HDR *) auth_win)->data;
	T_MMI_BT_Authorise_Data * data = (T_MMI_BT_Authorise_Data *)win_data->user;

	MFW_BT_TRACE ("bt_menu_mnu_cb()");

	switch (e)
	{
		case E_MNU_ESCAPE:
			bt_menu_destroy(win);
			data->bt_auth_menu = 0;
			break;

		default:
			return 0;
	}

	return 1;
}

static int bt_menu_win_cb (MfwEvt e, MfwWin *w)
{
	T_bt_menu * data = (T_bt_menu *)w->user;
	MfwMnu * mnu;

	MFW_BT_TRACE ("bt_menu_win_cb()");
	
	switch (e)
	{
		case MfwWinVisible:
			mnu = (MfwMnu *)mfwControl(data->menu);
			softKeys_displayId(TxtSoftSelect, TxtSoftBack, 0, mnu->curAttr->mnuColour );
			break;

		default:
			return 0;
	}
	return 1;
}

static int bt_menu_kbd_cb (MfwEvt e, MfwKbd *k)
{
	T_MFW_HND	win  = mfwParent(mfw_header());
	T_MFW_WIN	*win_data = ((T_MFW_HDR *)win)->data;
	T_bt_menu	*data = (T_bt_menu *)win_data->user;

	T_VOID_FUNC cancel_cb;

	MFW_BT_TRACE ("bt_menu_kbd_cb()");


	switch (k->code)
	{
		case KCD_MNUUP:
			mnuUp(data->menu);
			winShow(win);
			break;

		case KCD_MNUDOWN:
			mnuDown(data->menu);
			winShow(win);
			break;

		case KCD_LEFT:
			mnuSelect(data->menu);
			{
				MfwMnu *mnu;
				mnu = (MfwMnu *) mfwControl( data->menu );
				if (mnu != NULL)
				{
					if (mnu->curAttr != NULL)
						softKeys_displayId( TxtSoftSelect, TxtSoftBack, 0, mnu->curAttr->mnuColour);
				}
			}
			break;

		case KCD_RIGHT:
		case KCD_HUP:
			cancel_cb = data->cancel_cb;
			mnuEscape(data->menu);

			cancel_cb();
			break;

		default:
			return MFW_EVENT_CONSUMED;
	}
	return MFW_EVENT_CONSUMED;
}

static int bt_menu_kbd_long_cb (MfwEvt e, MfwKbd *k)
{
	T_MFW_HND       win  = mfwParent(mfw_header());
	T_MFW_WIN     * win_data = ((T_MFW_HDR *)win)->data;
	T_bt_menu * data = (T_bt_menu *)win_data->user;


	MFW_BT_TRACE ("bt_menu_kbd_long_cb()");

	if ((e & KEY_CLEAR) && (e & KEY_LONG))
	{
		mnuEscape(data->menu);
		return MFW_EVENT_CONSUMED;
	}
	
	return  MFW_EVENT_CONSUMED;
}

static void mmi_bt_authorize_editor_cb(T_MFW_HND win, USHORT identifier, SHORT reason)
{
	MfwHnd auth_win = bt_data.bt_authorize_win;
	T_MFW_WIN		* win_data = ((T_MFW_HDR *) auth_win)->data;
	T_MMI_BT_Authorise_Data * data = (T_MMI_BT_Authorise_Data *)win_data->user;
	
	MFW_BT_TRACE("bt_auth_editor_cb()");
	
	switch (reason)
	{
		case INFO_KCD_RIGHT:
		case INFO_KCD_HUP:
			/*
			** CQ22021 : The Editor is destroyed automatically, reset the win value to NULL
			*/
			 data->bt_auth_info_editor = (void *)0;

			/*
			** Free the dynamically allocated memory
			*/
			mfwFree(data->bt_auth_info_text, data->bt_auth_info_text_size);
			break;

		default:
			/* otherwise no action to be performed
			*/
			break;
	}

	return;
}

static int mmi_bt_authorize_display_info(MfwMnu* m, MfwMnuItem* i)
{
	T_MFW_HND	auth_win = bt_data.bt_authorize_win;
	T_MFW_WIN   * win_data = ((T_MFW_HDR *) auth_win)->data;
	T_MMI_BT_Authorise_Data * data = (T_MMI_BT_Authorise_Data *)win_data->user;

	USHORT			reqBufSize = 0;
	USHORT			serviceTxtId = TxtNotSupported;
#ifdef NEW_EDITOR
	T_AUI_EDITOR_DATA	editor_data;
#endif
	
	MFW_BT_TRACE("mmi_bt_authorize_display_info()");
	
	/*
	** Get the Text Id to be used to represent the service
	*/
	switch(data->bt_auth_req_param->service)
	{
		case BTA_SPP_SERVICE_ID:
			serviceTxtId = TxtBtSerialPort;
			break;

		case BTA_DUN_SERVICE_ID:
			serviceTxtId = TxtBtDialUpNetworking;
			break;

		case BTA_FAX_SERVICE_ID:
			serviceTxtId = TxtFax;
			break;

		case BTA_HSP_SERVICE_ID:
			serviceTxtId = TxtBtHeadSet;
			break;

		case BTA_HFP_SERVICE_ID:
			serviceTxtId = TxtBtHandsFree;
			break;

		case BTA_OP_SERVICE_ID:
			serviceTxtId = TxtBtObjectPush;
			break;

		case BTA_FT_SERVICE_ID:
			serviceTxtId = TxtBtFileTransfer;
			break;
	}

	/*
	** Calculate the size of Buffer required this will give a little extra ... not not much.
	*/
	reqBufSize = BT_MAX_DISPLAY_DEV_NAME_LENGTH; // The max length of the dev name was ensured when the event was received
	reqBufSize += strlen(MmiRsrcGetText(TxtBtRequiresAuthorizationForService));
	reqBufSize += strlen(MmiRsrcGetText(serviceTxtId));
	reqBufSize += 6; // Added for CR/Lf to ensure enough space

	/*
	** Allocate enough memory for the display text
	*/
	data->bt_auth_info_text = mfwAlloc(reqBufSize);

	if (data->bt_auth_info_text == 0)
	{
		/*
		** Display an error dialog and return
		*/
		mmi_bluetooth_show_info(data->win, TxtFailed, TxtErrorOutOfMem);
		return MFW_EVENT_CONSUMED;
	}

	data->bt_auth_info_text_size = reqBufSize;

	sprintf((char *)data->bt_auth_info_text, MmiRsrcGetText(TxtBtRequiresAuthorizationForService),
		     (char *)data->bt_auth_req_param->bd_name,
		     (char *)MmiRsrcGetText(serviceTxtId));
	
#ifdef NEW_EDITOR
	/*
	** Initialise the editor
	*/
	AUI_edit_SetDefault(&editor_data);

	AUI_edit_SetBuffer(&editor_data, ATB_DCS_ASCII, data->bt_auth_info_text, data->bt_auth_info_text_size);
	AUI_edit_SetTextStr(&editor_data, TxtNull, TxtSoftBack, TxtBtInfo, TxtNull);
	AUI_edit_SetMode(&editor_data, ED_MODE_READONLY, ED_CURSOR_NONE);

	AUI_edit_SetEvents(&editor_data, 0, TRUE, FOREVER, mmi_bt_authorize_editor_cb);

	data->bt_auth_info_editor = AUI_edit_Start(data->win, &editor_data);
#endif

	return MFW_EVENT_CONSUMED;
}

static int mmi_bt_authorize_once(MfwMnu* m, MfwMnuItem* i)
{
	MfwHnd auth_win = bt_data.bt_authorize_win;
	T_MFW_WIN		* win_data = ((T_MFW_HDR *) auth_win)->data;
	T_MMI_BT_Authorise_Data * data = (T_MMI_BT_Authorise_Data *)win_data->user;
	T_MFW_BT_STATUS	btRetVal;

	MFW_BT_TRACE("mmi_bt_authorize_once()");

	/*
	** Send the appropriate response to Bluetooth
	*/
	btRetVal = mfw_bt_dm_authorize_resp(MFW_BT_AUTH_ONCE);

	/*
	** Destroy the Menu
	*/
	if (data->bt_auth_menu != 0)
		bt_menu_destroy(data->bt_auth_menu);

	/*
	** Free the Allocated Memory
	*/
	mfwFree((U8 *)data->bt_auth_req_param, (U16)sizeof(T_MFW_BT_DM_AUTHORIZE_REQ));
	data->bt_auth_req_param = (void *)0;

	/*
	** Destroy the Authorization Window
	*/
	mmi_bt_authorize_destroy(data->win);
	
	return MFW_EVENT_CONSUMED;

}

static int mmi_bt_authorize_always(MfwMnu* m, MfwMnuItem* i)
{
	MfwHnd auth_win = bt_data.bt_authorize_win;
	T_MFW_WIN		* win_data = ((T_MFW_HDR *) auth_win)->data;
	T_MMI_BT_Authorise_Data * data = (T_MMI_BT_Authorise_Data *)win_data->user;
	T_MFW_BT_STATUS	btRetVal;

	MFW_BT_TRACE("bt_authorize_always()");

	/*
	** Send the appropriate response to Bluetooth
	*/
	btRetVal = mfw_bt_dm_authorize_resp(MFW_BT_AUTH_ALWAYS);

	/*
	** Destroy the Menu
	*/
	if (data->bt_auth_menu != 0)
		bt_menu_destroy(data->bt_auth_menu);

	/*
	** Free the Allocated Memory
	*/
	mfwFree((U8 *)data->bt_auth_req_param, (U16)sizeof(T_MFW_BT_DM_AUTHORIZE_REQ));
	data->bt_auth_req_param = (void *)0;

	/*
	** Destroy the Authorization Window
	*/
	mmi_bt_authorize_destroy(data->win);
	
	return MFW_EVENT_CONSUMED;

}

static int mmi_bt_dont_authorize(MfwMnu* m, MfwMnuItem* i)
{
	MfwHnd auth_win = bt_data.bt_authorize_win;
	T_MFW_WIN		* win_data = ((T_MFW_HDR *) auth_win)->data;
	T_MMI_BT_Authorise_Data * data = (T_MMI_BT_Authorise_Data *)win_data->user;
	T_MFW_BT_STATUS	btRetVal;

	MFW_BT_TRACE("mmi_bt_dont_authorize()");

	/*
	** Send the appropriate response to Bluetooth
	*/
	btRetVal = mfw_bt_dm_authorize_resp(MFW_BT_AUTH_FAIL);

	/*
	** Destroy the Menu
	*/
	if (data->bt_auth_menu != 0)
		bt_menu_destroy(data->bt_auth_menu);

	/*
	** Free the Allocated Memory
	*/
	mfwFree((U8*)data->bt_auth_req_param, (U16)sizeof(T_MFW_BT_DM_AUTHORIZE_REQ));
	data->bt_auth_req_param = (void *)0;

	/*
	** Destroy the Authorization Window
	*/
	mmi_bt_authorize_destroy(data->win);

	return MFW_EVENT_CONSUMED;
}

static void mmi_bt_authorize_rsk(void)
{
	MfwHnd auth_win = bt_data.bt_authorize_win;
	T_MFW_WIN		* win_data = ((T_MFW_HDR *) auth_win)->data;
	T_MMI_BT_Authorise_Data * data = (T_MMI_BT_Authorise_Data *)win_data->user;
	T_MFW_BT_STATUS	btRetVal;

	MFW_BT_TRACE("bt_authorize_rsk()");

	/*
	** Send the appropriate response to Bluetooth
	*/
	btRetVal = mfw_bt_dm_authorize_resp(MFW_BT_AUTH_FAIL);

	/*
	** Destroy the Menu
	*/
	if (data->bt_auth_menu != 0)
		bt_menu_destroy(data->bt_auth_menu);

	/*
	** Menu will be destroyed automatically by Right Softkey Press
	** Free the Allocated Memory
	*/
	mfwFree((U8 *)data->bt_auth_req_param, (U16)sizeof(T_MFW_BT_DM_AUTHORIZE_REQ));
	data->bt_auth_req_param = (void *)0;

	/*
	** Destroy the Authorization Window
	*/
	mmi_bt_authorize_destroy(data->win);

	return;
}

static int bt_srch_dev_pair (MfwMnu * mnu, MfwMnuItem * item)
{
	MFW_BT_TRACE("bt_srch_dev_pair()");

	SEND_EVENT(bt_srch_data.win, BT_PAIR_DEVICE, 0, 0);

	return MFW_EVENT_CONSUMED;
}

static int bt_srch_dev_show_services (MfwMnu * mnu, MfwMnuItem * item)
{
	MFW_BT_TRACE("bt_srch_dev_show_services()");

	SEND_EVENT(bt_srch_data.win, BT_SHOW_DEV_SERVICES, 0, 0);

	return MFW_EVENT_CONSUMED;
}

/*
**	CQ21843 : Menu Action function
*/
static int bt_srch_dev_set_name (MfwMnu * mnu, MfwMnuItem * item)
{
	T_MFW_BT_STATUS btRetVal;
	T_MMI_BtData *data = &bt_data;
	T_MFW_BT_REM_DEVICE_INFO *cur_device;
	
	MfwHnd win = mfw_parent(mfw_header());

	MFW_BT_TRACE("bt_srch_dev_set_name()");

	cur_device = &bt_srch_data.srch_bt_dev_list[bt_srch_data.srch_bt_cur_dev_idx];

	if (data->bt_dev_name_win == (void *)0)
	{
		data->bt_DevNameForStartup = FALSE;

		data->bt_dev_name_win = mmi_bt_dev_name_create(win);

		if (data->bt_dev_name_win != (void *)0)
		{
			SEND_EVENT(data->bt_dev_name_win, BT_SET_REM_DEV_NAME, 0, (void *)cur_device);
		}
		else
		{
			MFW_BT_TRACE("bt_srch_dev_set_name() : Unable to create Device Name Win!");
		}
	}
	else
	{
		MFW_BT_TRACE("bt_srch_dev_set_name() : Device Name Win already active");
	}
	return MFW_EVENT_CONSUMED;
}

static int bt_srch_dev_add_known (MfwMnu * mnu, MfwMnuItem * item)
{
	T_MFW_BT_STATUS btRetVal;
	T_MFW_BT_REM_DEVICE_INFO *cur_device;


	cur_device = &bt_srch_data.srch_bt_dev_list[bt_srch_data.srch_bt_cur_dev_idx];
	MFW_BT_TRACE_P7("bt_srch_dev_add_known(), Idx %d, BD_ADDR 0x%02x%02x%02x%02x%02x%02x",
					     bt_srch_data.srch_bt_cur_dev_idx,
					     cur_device->bd_addr[0],
					     cur_device->bd_addr[1],
					     cur_device->bd_addr[2],
					     cur_device->bd_addr[3],
					     cur_device->bd_addr[4],
					     cur_device->bd_addr[5]);

	/*
	** CQ21834 : Ensure that the is_new value is set before writing the data to Flash, so that it will be
	**			set correctly when  the handset is restarted.
	*/
	cur_device->is_new = FALSE;

	btRetVal = mfw_bt_dm_add_device(cur_device->bd_addr);

	if (btRetVal != MFW_BT_SUCCESS)
	{
		/*
		** CQ21834 : Failed to write the data to Flash, continue to treat the device as unknown.
		*/
		cur_device->is_new = TRUE;
		MFW_BT_TRACE_P1("mfw_bt_dm_add_device returned error : %d", btRetVal);
		mmi_bluetooth_show_info(0, TxtFailed, TxtNull);
	}
	else
	{
		winShow(mfw_parent(mfw_header()));
	}
	
	return MFW_EVENT_CONSUMED;
}

static int bt_srch_dev_rem_known (MfwMnu * mnu, MfwMnuItem * item)
{
	T_MFW_BT_STATUS btRetVal;
	T_MFW_BT_REM_DEVICE_INFO *cur_device;

	MFW_BT_TRACE("bt_srch_dev_rem_known()");

	cur_device = &bt_srch_data.srch_bt_dev_list[bt_srch_data.srch_bt_cur_dev_idx];

	btRetVal = mfw_bt_dm_delete_device(cur_device->bd_addr);

	if (btRetVal != MFW_BT_SUCCESS)
	{
		MFW_BT_TRACE_P1("mfw_bt_dm_delete_device returned error : %d", btRetVal);
		mmi_bluetooth_show_info(0, TxtFailed, TxtNull);
	}
	else
	{
		cur_device->is_new = TRUE;
		cur_device->link_key_present = FALSE;

		winShow(mfw_parent(mfw_header()));
	}

	return MFW_EVENT_CONSUMED;
}

static void bt_srch_dev_list_searching_cb(T_MFW_HND Parent, ListMenuData * ListData)
{
	T_MFW_WIN			*win_data	= ((T_MFW_HDR *)Parent)->data;
	T_MMI_BtSearchData	*data		= (T_MMI_BtSearchData *)win_data->user;
	MfwMnuItem			*ptr_tempListItem;
	T_MFW_BT_REM_DEVICE_INFO	*ptr_tempDevDb;
	int iLoop;						/* CQ21841 : Loop identifier used while resetting the List labels */

	MFW_BT_TRACE("bt_srch_dev_list_searching_cb()");

	if ((ListData->Reason EQ LISTS_REASON_BACK) ||
	     (ListData->Reason EQ LISTS_REASON_CLEAR) ||
	     (ListData->Reason EQ LISTS_REASON_HANGUP))
	{
		/*
		** Change the mode of the list
		*/
		data->srch_bt_mode = BT_MODE_LIST_COMPLETE;

		/*
		** Stop the Search Now ... even if there are more entries waiting in the buffer, they will be ignored.
		*/
		mfw_bt_dm_cancel_search();

		/*
		** Destroy the window and recreate it
		*/
		listsDestroy(ListData->win);

		/*
		** Allocate memory to copy the devices already listed, copy the active data,
		** and free the memory set aside for ALL the devices to be listed.
		*/

		ptr_tempListItem = (MfwMnuItem *)mfwAlloc(data->srch_bt_device_count * sizeof(MfwMnuItem));
		if (ptr_tempListItem != (MfwMnuItem *)0)
		{
			/*
			** Copy the list of items
			*/
			memcpy(ptr_tempListItem, data->srch_bt_list_devices_menu_data.List, (data->srch_bt_device_count * sizeof(MfwMnuItem)));

			/*
			** Free the first (and larger) list
			*/
			mfwFree((U8 *)data->srch_bt_list_devices_menu_data.List, (U16)(data->srch_bt_num_devices * sizeof(MfwMnuItem)));

			data->srch_bt_list_devices_menu_data.List = ptr_tempListItem;
		}

		/*
		** Repeat for the 'Device List'
		*/
		ptr_tempDevDb = (T_MFW_BT_REM_DEVICE_INFO *)mfwAlloc(data->srch_bt_device_count * sizeof(T_MFW_BT_REM_DEVICE_INFO));
		if (ptr_tempDevDb!= (T_MFW_BT_REM_DEVICE_INFO *)0)
		{
			/*
			** Copy the list of devices
			*/
			memcpy(ptr_tempDevDb, data->srch_bt_dev_list, (data->srch_bt_device_count * sizeof(T_MFW_BT_REM_DEVICE_INFO)));

			/*
			** Free the first (and larger) list
			*/
			mfwFree((U8 *)data->srch_bt_dev_list, (U16)(data->srch_bt_num_devices * sizeof(T_MFW_BT_REM_DEVICE_INFO)));

			data->srch_bt_dev_list = ptr_tempDevDb;
		}

		/*
		** Configure some other List parameters
		*/
		data->srch_bt_num_devices = data->srch_bt_device_count;
		data->srch_bt_list_devices_menu_data.ListLength = data->srch_bt_device_count;
		data->srch_bt_list_devices_menu_data.Attr->nItems = data->srch_bt_device_count;

		data->srch_bt_list_devices_menu_data.Attr->hdrId = TxtBtDevices;

		data->srch_bt_list_devices_menu_data.LeftSoftKey = TxtSoftOptions;
		data->srch_bt_list_devices_menu_data.RightSoftKey = TxtSoftBack;

		/*
		** CQ21842 : Modify the List Key Events so that it handles all teh keys it requires.
		*/
		data->srch_bt_list_devices_menu_data.KeyEvents      = KEY_CLEAR | KEY_RIGHT | KEY_LEFT | KEY_MNUUP | KEY_MNUDOWN |KEY_HUP;

		data->srch_bt_list_devices_menu_data.autoDestroy = TRUE;

		data->srch_bt_dev_list_cb = (ListCbFunc)bt_srch_dev_list_listmnu_cb;

		/*
		** CQ21841 : For each device in the list, reset the string pointer because it will be pointing to the old device
		** list which has just been freed
		*/
		for (iLoop = 0; iLoop < data->srch_bt_num_devices; iLoop++)
 			data->srch_bt_list_devices_menu_data.List[iLoop].str = data->srch_bt_dev_list[iLoop].name;
 
		/*
		** Recreate the menu with the new details;
		*/
		if (listDisplayListMenu(data->win, &data->srch_bt_list_devices_menu_data, data->srch_bt_dev_list_cb, FALSE) != LISTS_FAIL)
			data->srch_bt_dev_list_win = data->srch_bt_list_devices_menu_data.win;

	}

	return;
}

static void bt_srch_dev_list_listmnu_cb(T_MFW_HND Parent, ListMenuData * ListData)
{
	T_MFW_WIN			*win_data	= ((T_MFW_HDR *)Parent)->data;
	//T_MMI_BtSearchData	*data		= (T_MMI_BtSearchData *)win_data->user;
	T_MMI_BtSearchData	*data		= &bt_srch_data;
	MfwMnuItem			*ptr_tempListItem;
	T_MFW_BT_REM_DEVICE_INFO	*ptr_tempDevDb;

	MFW_BT_TRACE_P1("bt_srch_dev_list_listmnu_cb(), with reason %d", ListData->Reason);

	if ((ListData->Reason EQ LISTS_REASON_BACK) ||
	     (ListData->Reason EQ LISTS_REASON_CLEAR) ||
	     (ListData->Reason EQ LISTS_REASON_HANGUP))
	{
		/*
		** Destroy the window --- Not sure if this is required! ... leave it out for now
		*/
		 listsDestroy(ListData->win);

		/*
		** Free the memory set aside for ALL the devices to be listed.
		** CQ21834 : Use the "ListLength" value as this will also include the "No Devices" Entry for Known Devices.
		*/
		mfwFree((U8 *)data->srch_bt_list_devices_menu_data.List, (U16)(data->srch_bt_list_devices_menu_data.ListLength * sizeof(MfwMnuItem)));
		data->srch_bt_list_devices_menu_data.List = (void *)0;

		/*
		** Repeat for the 'Device List'
		*/
		mfwFree((U8 *)data->srch_bt_dev_list, (U16)(data->srch_bt_num_devices * sizeof(T_MFW_BT_REM_DEVICE_INFO)));
		data->srch_bt_dev_list = (void *)0;

		/*
		** Configure some other List parameters
		*/
		data->srch_bt_num_devices = 0;
		data->srch_bt_device_count = 0;
		data->srch_bt_list_devices_menu_data.ListLength = 0;
		data->srch_bt_list_devices_menu_data.Attr->nItems = 0;

		data->srch_bt_list_devices_menu_data.Attr->hdrId = 0;

		data->srch_bt_list_devices_menu_data.LeftSoftKey = 0;
		data->srch_bt_list_devices_menu_data.RightSoftKey = 0;
		data->srch_bt_list_devices_menu_data.autoDestroy = TRUE;

		data->srch_bt_dev_list_cb = (ListCbFunc)0;

		data->srch_bt_dev_list_win = 0;
		data->srch_bt_mode = BT_MODE_NO_SEARCH;

		/*
		** Destroy the "Bt Search Window" and return to the underlying Menu
		*/
		SEND_EVENT(data->win, BT_DISABLE_SEARCH, 0, 0);

	}

	return;
}

static void bt_srch_service_list_listmnu_cb(T_MFW_HND Parent, ListMenuData * ListData)
{
	T_MFW_WIN			*win_data	= ((T_MFW_HDR *)Parent)->data;
	T_MMI_BtSearchData	*data		= (T_MMI_BtSearchData *)win_data->user;
	MfwMnuItem			*ptr_tempListItem;
	T_MFW_BT_REM_DEVICE_INFO	*ptr_tempDevDb;

	MFW_BT_TRACE("bt_srch_service_list_listmnu_cb()");

	if ((ListData->Reason EQ LISTS_REASON_BACK) ||
	     (ListData->Reason EQ LISTS_REASON_CLEAR) ||
	     (ListData->Reason EQ LISTS_REASON_HANGUP))
	{
		/*
		** Destroy the window --- Not sure if this is required! ... leave it out for now
		*/
		listsDestroy(ListData->win);

		/*
		** Free the memory set aside for ALL the devices to be listed.
		*/
		mfwFree((U8 *)data->srch_bt_show_services_menu_data.List, (U16)(data->srch_bt_show_services_menu_data.ListLength * sizeof(MfwMnuItem)));
		data->srch_bt_show_services_menu_data.List = (void *)0;

		/*
		** Configure some other List parameters
		*/
		data->srch_bt_show_services_menu_data.ListLength = 0;
		data->srch_bt_show_services_menu_data.Attr->nItems = 0;

		data->srch_bt_show_services_menu_data.Attr->hdrId = 0;

		data->srch_bt_show_services_menu_data.LeftSoftKey = 0;
		data->srch_bt_show_services_menu_data.RightSoftKey = 0;
		data->srch_bt_show_services_menu_data.autoDestroy = TRUE;

		data->srch_bt_show_services_win = 0;
	}

	return;
}

static int bt_count_dev_services(T_MFW_BT_SERVICE_MASK services, T_MFW_BT_SERVICE_MASK *srv_mask_arry)
{
	ULONG	chk_serv = 2;
	int		iLoop;
	int		iCount = 0;

	MFW_BT_TRACE_P1("bt_count_dev_services() : services 0x%08lx", services);

	for (iLoop = BTA_RES_SERVICE_ID + 1; iLoop < BTA_MAX_SERVICE_ID ; iLoop++)
	{
		MFW_BT_TRACE_P4("bt_count_dev_services > Idx %d, Count %d, Services 0x%08lx, chk_srv 0x%08lx",
							iLoop, iCount, services, chk_serv);
		
			if ((services & chk_serv) != 0)
			{
				MFW_BT_TRACE_P2("bt_count_dev_services > Idx %d, Service 0x%08lx", iCount, chk_serv);
				srv_mask_arry[iCount] = chk_serv;
				
				iCount++;
			}

			chk_serv *= 2;
	}

	MFW_BT_TRACE_P1("bt_count_dev_services > Number of Services Found : %d" , iCount);

	return iCount;
}

static int bt_get_TxtId_for_service(T_MFW_BT_SERVICE_MASK service)
{
	int TxtId;
	
	MFW_BT_TRACE("bt_get_TxtId_for_service()");

	switch (service)
	{
		case BTA_SPP_SERVICE_MASK:
			TxtId = TxtBtSerialPort;
			break;

		case BTA_DUN_SERVICE_MASK:
			TxtId = TxtBtDialUpNetworking;
			break;

		case BTA_FAX_SERVICE_MASK:
			TxtId = TxtFax;
			break;

		case BTA_LAP_SERVICE_MASK:
			TxtId = TxtBtLanAccess;
			break;

		case BTA_HSP_SERVICE_MASK:
			TxtId = TxtBtHeadSet;
			break;

		case BTA_HFP_SERVICE_MASK:
			TxtId = TxtBtHandsFree;
			break;

		case BTA_OP_SERVICE_MASK:
			TxtId = TxtBtObjectPush;
			break;

		case BTA_FT_SERVICE_MASK:
			TxtId = TxtBtFileTransfer;
			break;

		case BTA_CT_SERVICE_MASK:
			TxtId = TxtBtCordlessTelephony;
			break;

		case BTA_IC_SERVICE_MASK:
			TxtId = TxtBtIntercom;
			break;

		default:
			TxtId = TxtBtUnknownService;			
	}

	return TxtId;
}

