view src/aci2/mfw/mfw_bt_dm.c @ 662:8cd8fd15a095

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

/*
+-------------------------------------------------------------------+
| PROJECT: MMI-Framework (8445)		$Workfile:: mfw_bt_dm.c			$|
| $Author:: NDH						$Revision::  1						$|
| CREATED: 22.04.04					$Modtime:: 22.04.04 11:07			$|
| STATE  : code														 |
+-------------------------------------------------------------------+


   MODULE  : MFW_BT_DM

   PURPOSE : This module contains the functions for MFW Bluetooth Device Manager Profile


*/

#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"

#else

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

#endif

#include "bta_riviera.h"
#include "mfw_bte.h"
#include "mfw_bt_dm.h"
#include "mfw_bt_geh.h"
#include "mfw_bt_flash.h"


T_MFW_BT_CB 			mfw_bt_cb;

/* file where is stored bd address of the device to connect */
#ifndef MFW_BT_BD_ADDR_FILE
#define MFW_BT_BD_ADDR_FILE "/bt/remote_bd"
#endif

static T_MFW_BT_STATUS mfw_bt_dm_trust_device(BOOLEAN is_trusted, BD_ADDR bd_addr);


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

 $Function:		mfw_bt_dm_set_visibility

 $Description:		set visibility of local BT device

 $Returns:		T_MFW_BT_STATUS. Success or fail.	

 $Arguments:		is_visible: new visibility setting. is_temp: define whether it is a temporary
 				modification ( TRUE ) or a permanent one ( FALSE ).

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_dm_set_visibility( BOOL is_visible, BOOL is_temp)
{
	/* other devices will be able to find this device during an inquiry */
	if( mfw_bt_cb.is_started == TRUE )
		BTA_DmSetVisibility( 	(is_visible)?BTA_DM_GENERAL_DISC:BTA_DM_NON_DISC, 
    								BTA_DM_CONN);	

	if( is_temp == TRUE)
		/* it looks like this is only a temporary change  => don't store that in flash! */
		return MFW_BT_SUCCESS;

	/* update to nvram and mfw_bt_cfg */
    	return mfw_bt_store_visibility( is_visible );
}

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

 $Function:		mfw_bt_dm_get_visibility

 $Description:		get visibility of local BT device

 $Returns:		TRUE if visible, FALSE if not.

 $Arguments:		none

*******************************************************************************/
BOOL mfw_bt_dm_get_visibility( void )
{
	return mfw_bt_read_visibility( );
}



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

 $Function:		mfw_bt_dm_get_local_name

 $Description:		read  local BT device name

 $Returns:		a pointer to a string. NULL if no name available. One should make a copy of
 				string if he wants to use it/modify it. 

 $Arguments:		none

*******************************************************************************/
UINT8 * mfw_bt_dm_get_local_name( void )
{
	return mfw_bt_read_local_name();
}




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

 $Function:		mfw_bt_dm_set_local_name

 $Description:		set local BT device name

 $Returns:		T_MFW_BT_STATUS	

 $Arguments:		new name. Pointer to a string. This string is copied locally. Buffer is not freed.

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_dm_set_local_name( INT8 *name )
{
	if( strlen((char*)name) == 0 )
	{
		/* BMI should never ever send back an empty string, except at start-up */
		if( mfw_bt_cb.is_name_requested == FALSE )
			return MFW_BT_FAIL;
		
		/* we are here, this means:
			- it's a start-up
			- apparently, the local name was never set. => it's the first start-up
			- the user don't really want to use BT as he cancelled the setting.
		=> this means we do want to stop BT... So go for it!  :o)  */
		mfw_bt_disable( );
		return MFW_BT_SUCCESS;
	}	

	if( mfw_bt_cb.is_name_requested == TRUE )
		mfw_bt_cb.is_name_requested = FALSE;

	if( strlen((char*)name) > MFW_BT_NAME_LENGTH )
		return MFW_BT_INVALID_DATA;
	
	if( mfw_bt_cb.is_started )
		BTA_DmSetDeviceName( (char*)name );
	/* update to nv memory and mfw_bt_cfg with new name */
	return mfw_bt_store_local_name( (char*) name );
}

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

 $Function:		mfw_bt_dm_get_bt_status

 $Description:		get the status of the local Bluetooth system. Used at start-up to decide whether
 				or not we want BT to be started by default.

 $Returns:		MFW_BT_SUCCESS is BT is started. 0 if OFF	

 $Arguments:		

*******************************************************************************/
BOOL mfw_bt_dm_get_bt_status( void )
{
	return mfw_bt_read_status( );

}





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

 $Function:		mfw_bt_dm_pin_code

 $Description:		used by BMI to send back a pin code

 $Returns:		T_MFW_BT_STATUS. 	MFW_BT_NOT_INITIALISED is BT is not started.

 $Arguments:		pin code and pin code length. This data is copied.

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_dm_pin_code(UINT8* pin_code, UINT8 pin_len)
{
	BOOLEAN accept = TRUE;

	if( mfw_bt_cb.is_started != TRUE )
		return MFW_BT_NOT_INITIALISED;
	
	if(pin_len == 0)
	    accept = FALSE;
	BTA_DmPinReply( 	mfw_bt_cb.peer_bdaddr, 
	                			accept,   
	                			pin_len, 
	                			pin_code);

	return MFW_BT_SUCCESS;
}



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

 $Function:		mfw_bt_dm_bond

 $Description:		used by BMI to send a pin code in order to establish a bonding with a 
 				remote device.

 $Returns:		T_MFW_BT_STATUS. MFW_BT_NOT_INITIALISED is BT is not started.
 				

 $Arguments:		BD_ADDR of the remote device, pin code and pin code length. Data is copied.

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_dm_bond(BD_ADDR bd_addr, UINT8* pin_code, UINT8 pin_len )
{
	if( mfw_bt_cb.is_started != TRUE )
		return MFW_BT_NOT_INITIALISED;
	

	MFW_BT_TRACE("try to bond with stored device");
	if(pin_len != 0)
	{
		/* now tell the BT stack */
		BTA_DmBond (	bd_addr,	pin_len,  pin_code );		
		return MFW_BT_SUCCESS;		
	}
	else
	{
		MFW_BT_TRACE("  [ mfw_bt dm bond]: no pin code entered!");
		return MFW_BT_FAIL;
	}

}


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

 $Function:		mfw_bt_dm_authorize_resp

 $Description:		used to answer to an authorization request

 $Returns:		T_MFW_BT_STATUS. SUCCESS/FAIL, but also:
 				MFW_BT_NOT_INITIALISED is BT is not started. 
 				MFW_BT_INVALID_DATA if auth value is not correct.
 				MFW_BT_UNKNOWN_DEVICE if BD_addr is not recognized.
 				MFW_BT_DATA_BASE_FULL if there are already too many devices in the DB.
 				

 $Arguments:		MFW_BT_AUTH_FAIL to refuse, 
 				MFW_BT_AUTH_ONCE to grant access temporarily,
 				MFW_BT_AUTH_ALWAYS to grant permanent access

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_dm_authorize_resp( T_MFW_BT_AUTHORIZE auth)
{
	T_MFW_BT_STATUS status;
	
	if( mfw_bt_cb.is_started != TRUE )
		return MFW_BT_NOT_INITIALISED;
	
	switch (auth)
	{
	case MFW_BT_AUTH_FAIL:
		/* reject */
		BTA_DmAuthorizeReply(	mfw_bt_cb.peer_bdaddr, 
								mfw_bt_cb.peer_service,
		                     			BTA_DM_NOT_AUTH);
		mfw_bt_dm_trust_device( FALSE, mfw_bt_cb.peer_bdaddr );
		break;
		
	case MFW_BT_AUTH_ALWAYS:
		/*
		** CQ22024 : Set the device as Trusted, and Authorise it for this an all subsequent connections
		**			If writing to the Flash fails, proceed with the authorisation anyway.
		*/
		status = mfw_bt_dm_trust_device( TRUE, mfw_bt_cb.peer_bdaddr );

		/*
		** Even if we fail to write the information to the FLASH, we should continue with the
		** Authorisation procedure. If the device is unknown, the device will remain Authorised as
		** long as the Handset is not powered down (Not ideal, but better than refusing Authorisation all together)
		*/
		BTA_DmAuthorizeReply(	mfw_bt_cb.peer_bdaddr, 
								mfw_bt_cb.peer_service,
								BTA_DM_AUTH_PERM);
		break;
		
	case MFW_BT_AUTH_ONCE:
		/* CQ22024 : tell the BT stack we authorize the device, but for this connection only */
		BTA_DmAuthorizeReply(	mfw_bt_cb.peer_bdaddr, 
								mfw_bt_cb.peer_service,
								BTA_DM_AUTH_TEMP);
		break;

	default:
		return MFW_BT_INVALID_DATA;
	}
	return MFW_BT_SUCCESS;
}


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

 $Function:		mfw_bt_dm_sig_strength

 $Description:		ask for the link quality

 $Returns:		T_MFW_BT_STATUS. MFW_BT_NOT_INITIALISED if BT is not started.

 $Arguments:		T_MFW_BT_DM_SIG_STRENGTH sig_strength,  UINT16 period, 	BOOLEAN is_on
				See BTA documentation for more details.
				
*******************************************************************************/
T_MFW_BT_STATUS	mfw_bt_dm_sig_strength (	T_MFW_BT_DM_SIG_STRENGTH sig_strength,
													UINT16 period,
													BOOLEAN is_on )
{
	if( mfw_bt_cb.is_started != TRUE )
		return MFW_BT_NOT_INITIALISED;
	BTA_DmSignalStrength((tBTA_SIG_STRENGTH_MASK) sig_strength,  period,  is_on);
	return MFW_BT_SUCCESS;
}


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

 $Function:		mfw_bt_dm_get_known_devices

 $Description:		used by BMI to get the list of known devices for a specified condition: either a 
 				service mask, either a bd address ( union ). 
 				MFW will fill in the variables: pp_device => table of known devices
 				number_of_devices => number of devices.
 				MFW will allocate memory for each device found. It's up to BMI to free it!

 $Returns:		T_MFW_BT_STATUS. 
 				If BD_ADDR is specified, might return MFW_BT_UNKNOWN_DEVICE.
 				 The answers will be returned using BMI signals:
 				- E_BT_DM_INQ_CMPL with the number of devices
 				- E_BT_DM_DISC_RES for each device
 				- then E_BT_DM_DISC_CMPL when it's done.
 
 $Arguments:		BD_ADDR if looking for a particular device. services if looking for a 
 				category of device. If bd_addr is specified, ignore services. If services set
 				to 0, will return all the known devices.

*******************************************************************************/
void mfw_bt_dm_get_known_devices ( 	BD_ADDR bd_addr,
											T_MFW_BT_SERVICE_MASK services)
{
	T_MFW_BT_REM_DEVICE *ptr_db_device[MFW_BT_NUM_REM_DEVICE];
	UINT8 i, number_of_devices;
	T_MFW_BT_DM_INQ_CMPL inq_cmpl_res;
	T_MFW_BT_STATUS status;
	BD_ADDR null_bd_addr;
	
	number_of_devices = 0;
	memset(&null_bd_addr[0], 0x00, sizeof(BD_ADDR));
	
	/* we have a BT address, try to find the related data */
	/* CQ21834 : cannot treat bd_addr as a pointer, because it is passed by value. Use MemCmp */
	if( memcmp(&bd_addr[0], &null_bd_addr[0], sizeof(BD_ADDR)) != 0 )
	{
		ptr_db_device[0] = mfw_bt_get_device_info(bd_addr);
		
		if(ptr_db_device[0] != NULL)
		{
			if((ptr_db_device[0])->is_new == FALSE)
				number_of_devices = 1;
		}
	}
	else
	{
		/* Now we want to find all the devices which support the given services */
		mfw_bt_get_device_by_service(services, &ptr_db_device[0], &number_of_devices );
	}

	/* first send the number of found devices. this is important! BMI shouldn't do anything
	before he gets all the answer */
	inq_cmpl_res.num_resps = number_of_devices;
	mfw_bt_signal( E_BT_DM_INQ_CMPL, (void*)&inq_cmpl_res);
	
	if (number_of_devices > 0)
	{
		/*
		** CQ21834 : The incorrect structure was being used for the signal, so the data was never received by the BMI.
		*/
		T_MFW_BT_DM_DISC_RES disc_res;

		/* now for each device found, send a signal to BMI. This will copy the data! */	
		for( i=0; i<number_of_devices; i++ )
		{
			memcpy((void *)&disc_res, (void *)ptr_db_device[i], sizeof(disc_res));

			mfw_bt_signal( E_BT_DM_DISC_RES, (void *)&disc_res);
		}

		mfw_bt_signal( E_BT_DM_DISC_CMPL, NULL);
	}
	
	return;
	
}







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

 $Function:		mfw_bt_dm_trust_device

 $Description:		specify whether a remote device should or not be trusted ( => access granted )

 $Returns:		T_MFW_BT_STATUS	
 				success, failure, MFW_BT_UNKNOWN_DEVICE

 $Arguments:		BOOLEAN for the permission; BD address of the remote device

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_dm_trust_device(BOOLEAN is_trusted, BD_ADDR bd_addr)
{
	T_MFW_BT_REM_DEVICE * p_device;
	T_MFW_BT_STATUS status;
	
	/* check if we know this device*/
	if(( p_device = mfw_bt_get_device_info(bd_addr)) == NULL )
		/* unknown device... */
		return MFW_BT_UNKNOWN_DEVICE;
		
	p_device->is_trusted = is_trusted;
	if (( status = mfw_bt_flash_store_device(p_device)) != MFW_BT_SUCCESS )
		return status;

	/* update BTA with new settings */
	if( mfw_bt_cb.is_started )
	{
		if(p_device->link_key_present)
			BTA_DmAddDevice(bd_addr, p_device->link_key, BTA_ALL_SERVICE_MASK, is_trusted);
		else 
			BTA_DmAddDevice(bd_addr, NULL, BTA_ALL_SERVICE_MASK, is_trusted);
	}

	return MFW_BT_SUCCESS;
 }



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

 $Function:		mfw_bt_dm_delete_device

 $Description:		remove a device from the local DB
 
 $Returns:		T_MFW_BT_STATUS ( MFW_BT_SUCCESS, MFW_BT_FAIL, MFW_BT_UNKNOWN_DEVICE )	

 $Arguments:		BD address

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_dm_delete_device(BD_ADDR bd_addr)
{
	if( mfw_bt_cb.is_started )
		BTA_DmRemoveDevice (bd_addr);
	return mfw_bt_flash_delete_device(bd_addr);
}



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

 $Function:		mfw_bt_dm_add_device

 $Description:		This will store permanently a device in Flash.

 $Returns:		T_MFW_BT_STATUS
 				errors: MFW_BT_UNKNOWN_DEVICE, MFW_BT_DATA_BASE_FULL, 
 				

 $Arguments:		new BD address

*******************************************************************************/
 T_MFW_BT_STATUS mfw_bt_dm_add_device(BD_ADDR bd_addr)
{
	T_MFW_BT_REM_DEVICE *p_device;
	T_MFW_BT_STATUS status;
	
	MFW_BT_TRACE("mfw_bt_dm_add_device()");

	/* get the info about this device */
	if( ( p_device = mfw_bt_get_device_info( bd_addr)) == NULL)
		return MFW_BT_UNKNOWN_DEVICE;
	
	if( p_device->is_new == TRUE )
	{
		/*
		** 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.
		*/
		p_device->is_new = FALSE;
		if((status = mfw_bt_flash_store_device(p_device))!=MFW_BT_SUCCESS)
			return status;
	}
	
	/* update BTA device database */
	if( mfw_bt_cb.is_started )
	{
		if(p_device->link_key_present)
			BTA_DmAddDevice(p_device->bd_addr, p_device->link_key,
		                    p_device->trusted_services, p_device->is_trusted);
		else 
		    	BTA_DmAddDevice(p_device->bd_addr, NULL,
		                    p_device->trusted_services, p_device->is_trusted);
	}
	return MFW_BT_SUCCESS;

}



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

 $Function:		mfw_bt_dm_rename_device

 $Description:		modify the friendly name of a known ( already stored ) remote device

 $Returns:		T_MFW_BT_STATUS.
 				MFW_BT_UNKNOWN_DEVICE, DATA_BASE_FULL, MFW_BT_INVALID_DATA...

 $Arguments:		bd address of the remote device and the new name associated

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_dm_rename_device(BD_ADDR bd_addr, UINT8* new_name)
{
	T_MFW_BT_REM_DEVICE *p_device;

	if( ( p_device = mfw_bt_get_device_info( bd_addr)) == NULL )
		return MFW_BT_UNKNOWN_DEVICE;
	/* if this device is new ( == in the inq DB ), we don't want to do anything */
	if( p_device->is_new == TRUE )
		return MFW_BT_FAIL;
	/* verify the string is OK */
	if( strlen( (char*)new_name ) > MFW_BT_NAME_LENGTH )
		return MFW_BT_INVALID_DATA;
	strcpy(p_device->friendly_name, (char*)new_name );
	return mfw_bt_flash_store_device(p_device);
	
}






/*
**  Functions used to interact with the BT "search engine"
*/


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

 $Function:		mfw_bt_dm_discover_device

 $Description:		Discovers services on a device

 $Returns:		T_MFW_BT_STATUS. MFW_BT_NOT_INITIALISED if BT not started.	

 $Arguments:		bd address of the remote device to discover

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_dm_discover_device(BD_ADDR bd_addr)
{

    	T_MFW_BT_SERVICE_MASK client_services;

	if( mfw_bt_cb.is_started != TRUE )
		return MFW_BT_NOT_INITIALISED;

	/* remember it's an inquiry */
	mfw_bt_cb.is_discovery = TRUE;
	
	/* we need to find only services for which we can be in client role, plus HS/HF */
	client_services = ((BTA_SUPPORTED_CLIENT_SERVICES & \
	                                ~( BTA_DUN_SERVICE_MASK | BTA_FAX_SERVICE_MASK )) \
	                                | BTA_HSP_SERVICE_MASK | BTA_HFP_SERVICE_MASK );

	BTA_DmDiscover(bd_addr, BTA_ALL_SERVICE_MASK, (tBTA_DM_SEARCH_CBACK*)mfw_bt_dm_search_cb);

	return MFW_BT_SUCCESS;
}


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

 $Function:		mfw_bt_dm_is_discover

 $Description:	Checks if we are in discovering services process

 $Returns:		

 $Arguments:	None

*******************************************************************************/
UINT8 mfw_bt_dm_is_discover(void)
{
	return mfw_bt_cb.is_discovery;
}



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

 $Function:		mfw_bt_dm_cancel_search

 $Description:		cancel an ongoing search

 $Returns:		MFW_BT_NOT_INITIALISED if BT not started.	

 $Arguments:		

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_dm_cancel_search( void )
{
	if( mfw_bt_cb.is_started != TRUE )
		return MFW_BT_NOT_INITIALISED;
    	BTA_DmSearchCancel();
	return MFW_BT_SUCCESS;		
}


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

 $Function:		mfw_bt_dm_search

 $Description:		Searches for devices supporting the services specified. If services = 0, will 
 				return all the found devices regardless of their functionalities.

 $Returns:		MFW_BT_NOT_INITIALISED if BT not started.	

 $Arguments:		services. If

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_dm_search(T_MFW_BT_SERVICE_MASK services)
{
	tBTA_DM_INQ inq_params;
	UINT8 inq_index;

	if( mfw_bt_cb.is_started != TRUE )
		return MFW_BT_NOT_INITIALISED;
	mfw_bt_cb.is_discovery = FALSE;
	inq_params.mode = 0;
	inq_params.duration = MFW_BT_DEFAULT_INQ_DURATION;
	inq_params.max_resps = MFW_BT_NUM_REM_DEVICE;
	inq_params.filter_type = BTA_DM_INQ_CLR;

	/* "initialize" the inquiry data base */
	mfw_bt_clean_inq_db( );
	/* store the services we are looking for, so that we can filter the results */
	mfw_bt_cb.search_services = services;
	/* find nearby devices */
	BTA_DmSearch(&inq_params, services, mfw_bt_dm_search_cb );
	return MFW_BT_SUCCESS;		
	
}




/*
** MFW Bluetooth Device Manager Signal Handler Function Definitions
*/
/*******************************************************************************

 $Function:		mfw_bt_dm_security_hndlr

 $Description:		This function recieves the BTA DM Security events from the Generic Event Handler
 				and either processes them in their entirety or passes them to the MMI for further
 				processing.

 $Returns:		MFW_BT_SUCCESS	: The signal was handled successfully

 $Arguments:		event	: Event Id returned from the Bluetooth Module
 				data		: pointer to the relevant data returned from the Mluetooth Module

*******************************************************************************/
T_MFW_BT_STATUS	mfw_bt_dm_security_hndlr (T_MFW_BT_DM_SEC_EVT event, T_MFW_BT_DM_SEC_SIG_DATA *data)
{
	T_MFW_BT_STATUS retVal = MFW_BT_SUCCESS;
	
	MFW_BT_TRACE("mfw_bt_dm_security_hndlr");

	switch (event)
	{
		case BTA_DM_SYS_START_EVT:
		{
			MFW_BT_TRACE("mfw_bt_dm_security_hndlr > BTA_DM_SYS_START_EVT event received");
			/* now enable bluetooth functionalities before calling other BTA API */
			BTA_EnableBluetooth(&mfw_bt_dm_security_cb);  
		}
		break;			
			
		case BTA_DM_ENABLE_EVT:
		{
			MFW_BT_TRACE("mfw_bt_dm_security_hndlr > BTA_DM_ENABLE_EVT event received");
			/* call the enable call-back */
			mfw_bt_enable_cb( );
		}
		break;

		case BTA_DM_DISABLE_EVT:
		{
			MFW_BT_TRACE("mfw_bt_dm_security_hndlr > BTA_DM_DISABLE_EVT event received");

			/* stop the BT chipset */
			BTA_SysStop();

			/* we won't use BT anymore => free the event handler */
			mfw_bt_ge_disable();
			
			/* store the new settings */
			mfw_bt_store_status(FALSE);
			mfw_bt_cb.is_started = FALSE;
			
			/* and tell BMI */
			mfw_bt_signal(E_BT_DISABLE_CMPL, (void *)0);
		}
		break;

		case BTA_DM_PIN_REQ_EVT:
		{
			/* store the BD ADDR of the remote device */
			bdcpy(mfw_bt_cb.peer_bdaddr, data->pin_req.bd_addr);
			/* and forward the signal to BMI */
			mfw_bt_signal(E_BT_DM_PIN_REQ, data);
			MFW_BT_TRACE("mfw_bt_dm_security_hndlr > BTA_DM_PIN_REQ_EVT event received");
		}
		break;

		case BTA_DM_AUTH_CMPL_EVT:
		{	
			T_MFW_BT_DM_AUTH_CMPL data_auth;
			T_MFW_BT_REM_DEVICE device;
			T_MFW_BT_REM_DEVICE *p_device;

			MFW_BT_TRACE("mfw_bt_dm_security_hndlr > BTA_DM_AUTH_CMPL_EVT event received");
			/* first, give some feedback to BMI */
			/* => copy data */
			memcpy(data_auth.bd_addr, data->auth_cmpl.bd_addr, BD_ADDR_LEN); 
			if( strlen((char*)data->auth_cmpl.bd_name) != 0 )
				mfwStrncpy((char*)data_auth.bd_name, (const char*)data->auth_cmpl.bd_name, MFW_BT_NAME_LENGTH);
			data_auth.is_success = data->auth_cmpl.success;
			/* and forward it */
			mfw_bt_signal(E_BT_DM_AUTH_CMPL, (void*)&data_auth);

			/* now see if we have to update our data base */
			p_device = mfw_bt_get_device_info(data->auth_cmpl.bd_addr);
			if( p_device == NULL )
			{	
				/* we don't know this device ... */ 
				if ( data->auth_cmpl.success == FALSE )
					/* ... and auth has been rejected: get away from here... */
					break;			
				
				/* ... but it's trusted. So add it to our DB. This means we have to create a 
				real T_MFW_BT_REM_DEVICE entity, which will be copied */
				p_device = &device;
				memset(&device, 0, sizeof( T_MFW_BT_REM_DEVICE ) );
			}
				
			/* ok, now  update our local DB: get the info we received */
			memcpy(p_device->bd_addr, data->auth_cmpl.bd_addr, BD_ADDR_LEN); 
			if( strlen((char*)data->auth_cmpl.bd_name) != 0 )
				mfwStrncpy((char*)p_device->name, (const char*)data->auth_cmpl.bd_name, MFW_BT_NAME_LENGTH);
			memcpy(p_device->link_key, data->auth_cmpl.key, LINK_KEY_LEN );
			p_device->link_key_present = data->auth_cmpl.key_present;

			/* we don't modify the other fields => either the already stored ones will be used, 
			either for a new device they will be set to zero. */
			
			mfw_bt_flash_store_device( p_device );			
		}
		break;

		case BTA_DM_AUTHORIZE_EVT:
		{
			/* keep a trace of the information??? */
			bdcpy(mfw_bt_cb.peer_bdaddr, data->authorize.bd_addr);
			strncpy((char*)mfw_bt_cb.peer_name, (char*)data->authorize.bd_name, MFW_BT_NAME_LENGTH);
			mfw_bt_cb.peer_service = data->authorize.service;
			/*and forward it to BMI */
			mfw_bt_signal(E_BT_DM_AUTHORIZE_REQ, data );
			MFW_BT_TRACE("mfw_bt_dm_security_hndlr > BTA_DM_AUTHORIZE_EVT event received");
		}
		break;

		case BTA_DM_LINK_UP_EVT:
		{	
			/* this is only a "HW" connection, so no service or name needed. Just show BT is busy */
			MFW_BT_TRACE("mfw_bt_dm_security_hndlr > BTA_DM_LINK_UP_EVT event received");
			mfw_bt_signal(E_BT_DM_LINK_UP, data );
		}
		break;

		case BTA_DM_LINK_DOWN_EVT:
		{	
			/* just to know BT is idle again */
			MFW_BT_TRACE("mfw_bt_dm_security_hndlr > BTA_DM_LINK_DOWN_EVT event received");
			mfw_bt_signal(E_BT_DM_LINK_DOWN, data );
		}
		break;

		case BTA_DM_SIG_STRENGTH_EVT:
		{	
			/* ok, we receive a signal strength indication. Great. */
			MFW_BT_TRACE("mfw_bt_dm_security_hndlr > BTA_DM_SIG_STRENGTH_EVT event received");
			mfw_bt_signal(E_BT_DM_SIG_STRENGTH_IND, data );
		}	
		break;

		default:
		{
			/*
			** Unexpected Event, set the data sized to -1 to exit with no further action
			*/
			MFW_BT_TRACE_P1("mfw_bt_dm_security_b > Unexpected Event %d", event);
			retVal = MFW_BT_INVALID_EVENT;
		}
		break;
			
	}

	return retVal;
}




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

 $Function:		mfw_bt_dm_search_hndlr

 $Description:		This function recieves the BTA DM Search events from the Generic Event Handler
 				and either processes them in their entirety or passes them to the MMI for further
 				processing.

 $Returns:		MFW_BT_SUCCESS	: The signal was handled successfully

 $Arguments:		event	: Event Id returned from the Bluetooth Module
 				data		: pointer to the relevant data returned from the Mluetooth Module

*******************************************************************************/
T_MFW_BT_STATUS	mfw_bt_dm_search_hndlr (T_MFW_BT_DM_SRCH_EVT event, T_MFW_BT_DM_SRCH_SIG_DATA *data)
{
	T_MFW_BT_STATUS retVal = MFW_BT_SUCCESS;
	
	MFW_BT_TRACE("mfw_bt_dm_search_hndlr");

	/*
	** Set the expected data size according to the received event
	*/
	switch (event)
	{
		case BTA_DM_INQ_RES_EVT:
			{
				MFW_BT_TRACE("mfw_bt_dm_search_hndlr > BTA_DM_INQ_RES_EVT event received");
				/* we just received a BD address... Don't even forward this to BMI */
			    	MFW_BT_TRACE_P6("DB_ADDR: msg_str%02x:%02x:%02x:%02x:%02x:%02x\n",
									data->inq_res.bd_addr[0], data->inq_res.bd_addr[1],
							              data->inq_res.bd_addr[2], data->inq_res.bd_addr[3],
							              data->inq_res.bd_addr[4], data->inq_res.bd_addr[5]);
				mfw_bt_add_inq_device( &(data->inq_res) );
			}
			break;

		case BTA_DM_INQ_CMPL_EVT:
			mfw_bt_signal( E_BT_DM_INQ_CMPL, (void*)&data->inq_cmpl);
			MFW_BT_TRACE("mfw_bt_dm_search_hndlr > BTA_DM_INQ_CMPL_EVT event received");
			break;

		case BTA_DM_DISC_RES_EVT:
		{
			T_MFW_BT_DM_DISC_RES disc_res_data;
			T_MFW_BT_REM_DEVICE *p_device_rec = NULL;	/*CQ21834 : Not Just needed for discovery, but search also */

			/*
			** Do some preliminary initialisation, so that if nothing changes we send the right information
			*/
			memset(&disc_res_data, 0x00, sizeof(T_MFW_BT_DM_DISC_RES));
			
			memcpy(disc_res_data.bd_addr, data->disc_res.bd_addr, sizeof(BD_ADDR));
			memcpy(disc_res_data.name, data->disc_res.bd_name, MFW_BT_NAME_LENGTH);
			disc_res_data.services = data->disc_res.services;	
			disc_res_data.is_new = TRUE;

			/* if we are doing a discovery on a device */
			if(mfw_bt_cb.is_discovery == TRUE)
			{
				if(data->disc_res.services == 0 )
				{
				    MFW_BT_TRACE("No service found");
				}
				else
				{
		                	p_device_rec = mfw_bt_get_device_info(data->disc_res.bd_addr );
		                	if(p_device_rec)
			              {
			              	/* we really should find our device! */ 
						p_device_rec->services = data->disc_res.services;
							
			              	if( p_device_rec->is_new)
							mfw_bt_add_disc_device((T_MFW_BT_DM_DISC_RES*) p_device_rec);
						else
							mfw_bt_flash_store_device(p_device_rec);
						/* forward the info to BMI */

						/*
						** Reset the information for the signal from the known or already discovered database
						*/
						memcpy(&disc_res_data, p_device_rec, sizeof(T_MFW_BT_DM_DISC_RES));
			              }
		            	}
		        }
		        /* we are doing device search. We receive the information about all the found devices. 
				Let's verify if we specified services to look for => if yes, filter the results */
		        else if( mfw_bt_cb.search_services == 0 ||  
					(mfw_bt_cb.search_services & data->disc_res.services))
		        {		
			/*
			** CQ21834 : Check to determine whether the device is already known, if so get (and update)
			** 			the information in th eKnown Devices Database
			*/
	                p_device_rec = mfw_bt_get_device_info(data->disc_res.bd_addr );

			/*
			** p_device_rec should not be NULL because the device was added to the inquiry database when the inq result
			** was recieved if it was not already in the known device database.
			*/
	                if (p_device_rec->is_new == FALSE)
		          {
		            MFW_BT_TRACE("BTA_DM_DISC_RES_EVT > This device is known");
				
		            if (strncmp(p_device_rec->name, (char *)&data->disc_res.bd_name, MFW_BT_NAME_LENGTH) != 0)
	              	{
	              		mfwStrncpy(p_device_rec->name, (char *)&data->disc_res.bd_name, MFW_BT_NAME_LENGTH);
	              	}

		            /* Update the device details! */ 
		                    p_device_rec->services |= data->disc_res.services;
				mfw_bt_flash_store_device(p_device_rec);

		            memcpy(&disc_res_data, p_device_rec, sizeof(T_MFW_BT_DM_DISC_RES));
	                }

		        /*
			** CQ21834: update our database whether the device is known or not, so that if the user removes it from the
			** known device database, we will still have the details available.
			*/
		        	mfw_bt_add_disc_device( (T_MFW_BT_DM_DISC_RES*) &disc_res_data);
		       }
		       
			MFW_BT_TRACE("mfw_bt_dm_search_hndlr > BTA_DM_DISC_RES_EVT event received");
			/* and forward the event to BMI */
			mfw_bt_signal( E_BT_DM_DISC_RES, (void*)&disc_res_data);			
		}
		break;

		case BTA_DM_DISC_CMPL_EVT:
			mfw_bt_signal( E_BT_DM_DISC_CMPL, NULL );
			MFW_BT_TRACE("mfw_bt_dm_search_hndlr > BTA_DM_DISC_CMPL_EVT event received");
			break;

		case BTA_DM_SEARCH_CANCEL_CMPL_EVT:
			/* currently, we don't do anything when a search is cancelled. Should we? */
			MFW_BT_TRACE("mfw_bt_dm_search_hndlr > BTA_DM_SEARCH_CANCEL_CMPL_EVT event received");
			break;

		default:
			/*
			** Unexpected Event, setthe data sized to -1 to exit with no further action
			*/
			MFW_BT_TRACE_P1("mfw_bt_dm_search_hndlr > Unexpected Event %d", event);
			retVal = MFW_BT_INVALID_EVENT;
			
	}

	return retVal;
}





/*
** MFW Bluetooth Device Manager Callback Function Definitions
*/
/*******************************************************************************

 $Function:		mfw_bt_dm_security_b

 $Description:		This is the Device Manager Security Callback function, a pointer to it is passed
 				to the Bluetooth Module in the BTA DM Enable function and it is used to return
 				information from the Bluetooth Module

 $Returns:		None

 $Arguments:		event	: Event Id returned from the Bluetooth Module
 				data		: pointer to the relevant data returned from the Mluetooth Module

*******************************************************************************/
void	mfw_bt_dm_security_cb(T_MFW_BT_DM_SEC_EVT event, T_MFW_BT_DM_SEC_SIG_DATA *data)
{
	int dataLen;
	T_MFW_BT_STATUS	geRetVal = MFW_BT_SUCCESS;

	MFW_BT_TRACE("mfw_bt_dm_security_b");

	/*
	** Set the expected data size according to the received event
	*/
	switch (event)
	{
		case BTA_DM_SYS_START_EVT:
			dataLen = 0;
			break;
		case BTA_DM_ENABLE_EVT:
			dataLen = sizeof(tBTA_DM_ENABLE);
			break;

		case BTA_DM_DISABLE_EVT:
			dataLen = 0;
			break;

		case BTA_DM_PIN_REQ_EVT:
			dataLen = sizeof(tBTA_DM_PIN_REQ);
			break;

		case BTA_DM_AUTH_CMPL_EVT:
			dataLen = sizeof(tBTA_DM_AUTH_CMPL);
			break;

		case BTA_DM_AUTHORIZE_EVT:
			dataLen = sizeof(tBTA_DM_AUTHORIZE);
			break;

		case BTA_DM_LINK_UP_EVT:
			dataLen = sizeof(tBTA_DM_LINK_UP);
			break;

		case BTA_DM_LINK_DOWN_EVT:
			dataLen = sizeof(tBTA_DM_LINK_DOWN);
			break;

		case BTA_DM_SIG_STRENGTH_EVT:
			dataLen = sizeof(tBTA_DM_SIG_STRENGTH);
			break;

		default:
			/*
			** Unexpected Event, setthe data sized to -1 to exit with no further action
			*/
			MFW_BT_TRACE_P1("mfw_bt_dm_security_b > Unexpected Event %d", event);
			dataLen = -1;
			
	}


	if (dataLen > 0)
	{
		/*
		** Data is expected with the received signal
		*/
		if ((void *)data == (void *)0)
		{
			/*
			** The data pointer is NULL, report the error
			*/
			MFW_BT_TRACE_P1("mfw_bt_dm_security_b > Event : %d, Data Pointer is NULL, but data is expected", event);
		}
		else
		{
			/*
			** Post the event and data to the Generic event handler
			*/
			geRetVal = mfw_bt_ge_post_event(MFW_BT_DM_SECURITY, (ULONG)event, (void *)data, dataLen);
		}
	}
	else if (dataLen == 0)
	{
		/*
		** There is no expected data with the received signal, post the event to the Generic event handler
		*/
		geRetVal = mfw_bt_ge_post_event(MFW_BT_DM_SECURITY, (ULONG)event, (void *)0, 0);
	}

	if (geRetVal != MFW_BT_SUCCESS)
	{
		/*
		** There is an error, but there is nothing that can be done other than to report it.
		*/
		MFW_BT_TRACE_P1("mfw_bt_dm_security_b > Failed to post the event. Error %d", geRetVal);
	}

	return;
}


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

 $Function:		mfw_bt_Dm_Search_Cb

 $Description:		This is the Device Manager Search Callback function, a pointer to it is passed
 				to the Bluetooth Module in the BTA DM Search and Discover functions and it is
 				used to return information from the Bluetooth Module

 $Returns:		None

 $Arguments:		event	: Event Id returned from the Bluetooth Module
 				data		: pointer to the relevant data returned from the Mluetooth Module

*******************************************************************************/
void	mfw_bt_dm_search_cb(T_MFW_BT_DM_SRCH_EVT event, T_MFW_BT_DM_SRCH_SIG_DATA *data)
{
	int dataLen;
	T_MFW_BT_STATUS	geRetVal = MFW_BT_SUCCESS;

	MFW_BT_TRACE("mfw_bt_Dm_Search_Cb");

	/*
	** Set the expected data size according to the received event
	*/
	switch (event)
	{
		case BTA_DM_INQ_RES_EVT:
			dataLen = sizeof(tBTA_DM_INQ_RES);
			break;

		case BTA_DM_INQ_CMPL_EVT:
			dataLen = sizeof(tBTA_DM_INQ_CMPL);
			break;

		case BTA_DM_DISC_RES_EVT:
			dataLen = sizeof(tBTA_DM_DISC_RES);
			break;

		case BTA_DM_DISC_CMPL_EVT:
			dataLen = 0;
			break;

		case BTA_DM_SEARCH_CANCEL_CMPL_EVT:
			dataLen = 0;
			break;


		default:
			/*
			** Unexpected Event, setthe data sized to -1 to exit with no further action
			*/
			MFW_BT_TRACE_P1("mfw_bt_Dm_Search_Cb > Unexpected Event %d", event);
			dataLen = -1;
			
	}


	if (dataLen > 0)
	{
		/*
		** Data is expected with the received signal
		*/
		if ((void *)data == (void *)0)
		{
			/*
			** The data pointer is NULL, report the error
			*/
			MFW_BT_TRACE_P1("mfw_bt_Dm_Search_Cb > Event : %d, Data Pointer is NULL, but data is expected", event);
		}
		else
		{
			/*
			** Post the event and data to the Generic event handler
			*/
			geRetVal = mfw_bt_ge_post_event(MFW_BT_DM_SEARCH, (ULONG)event, (void *)data, dataLen);
		}
	}
	else if (dataLen == 0)
	{
		/*
		** There is no expected data with the received signal, post the event to the Generic event handler
		*/
		geRetVal = mfw_bt_ge_post_event(MFW_BT_DM_SEARCH, (ULONG)event, (void *)0, 0);
	}

	if (geRetVal != MFW_BT_SUCCESS)
	{
		/*
		** There is an error, but there is nothing that can be done other than to report it.
		*/
		MFW_BT_TRACE_P1("mfw_bt_Dm_Search_Cb > Failed to post the event. Error %d", geRetVal);
	}

	return;
}