view src/aci2/mfw/mfw_bt_flash.c @ 638:cab2f315827e

FFS dev.c: added Spansion PL032J to the "generic" table With the discovery of first GTM900 and then Tango, it now appears that Openmoko was not the only manuf after all who kept TI's TCS211 firmware largely intact (as opposed to changing it beyond all recognition like Compal, Chi-Mei and BenQ did), thus we are now getting new "alien" targets on which we reuse the original manuf's FFS with IMEI and RF calibration tables as if it were native. On these targets we use the original device table for FFS, even though we previously thought that it would never apply to any target other than dsample, leonardo and gtamodem. We have previously added Samsung K5L33xxCAM (a new kind of multi-ID device) to the generic table to support its use in Huawei GTM900-B modules; now we got news that some slightly older GTM900-B specimen used S71PL032J instead, so we are now adding PL032J as well.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 30 Jan 2020 17:45:48 +0000
parents 93999a60b835
children
line wrap: on
line source

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


   MODULE  : MFW_BT_DB

   PURPOSE : This module contains the functions for MFW Bluetooth Data Base facilities. It is a LOCAL
   			DATA BASE, thus doesn't require the BT stack to be started. Just call the mfw_bt_flash_init( )
   			function to be able to use the following functions.


*/

#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 "mfw_ffs.h"
#include "mfw_bte.h"
#include "mfw_bt_dm.h"
#include "mfw_bt_geh.h"
#include "mfw_bt_flash.h"


/*****************************************************************************
 ** Constants. Please do not modify length of the parameters, because of alignement 
 constraints in flash
 *****************************************************************************/


/* this is the template for the conf file in case it does not exist or is corrupted */
 
static const tMFW_BT_CFG mfw_bt_default_cfg = {
    MFW_BT_ENABLED,
    MFW_BT_DISCOVERABLE_MODE,
    NULL
};

/* Also keep an image of the flash file in RAM */
static tMFW_BT_CFG mfw_bt_current_cfg;

/* we store the devices data base in a static structure because it will be loaded each time
the phone is powered on: there is no need here to allocate/free memory dynamically . */
static T_MFW_BT_REM_DEVICE mfw_bt_device_db[MFW_BT_NUM_REM_DEVICE];
const UINT8 MFW_BT_FLASH_DB_SIZE = MFW_BT_NUM_REM_DEVICE*sizeof(T_MFW_BT_REM_DEVICE);

/* newly found devices => RAM database */
static T_MFW_BT_REM_DEVICE 	mfw_bt_inq_db[MFW_BT_NUM_REM_DEVICE];


/*
* Local functions
*/

/* update the device data base in flash */
static int mfw_bt_flash_store_db(void);
/* load the device data base in RAM */
static int mfw_bt_flash_read_db(void);
/* store config file in flash */
static int mfw_bt_flash_store_cfg( void );
/* load config file in RAM */
static int mfw_bt_flash_read_cfg( void );



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

 $Function:		mfw_bt_flash_init

 $Description:		update the RAM information with the files in flash

 $Returns:		TRUE if OK, wrong is something failed => no stored file, and not possible to 
 				create a new one. Typically, this mean the flash is not formatted.

 $Arguments:		None

*******************************************************************************/
BOOL mfw_bt_flash_init( void )
{
	int status_db, status_cfg;
	/* first, read config file */
	status_cfg = mfw_bt_flash_read_cfg( );
	/* then load the saved device data base in RAM */
	status_db = mfw_bt_flash_read_db( );
	if( status_cfg < 0 || status_db < 0 )
		/* something wrong happened, notify it */
		return FALSE;

	return TRUE;
}




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

 $Function:		mfw_bt_read_status

 $Description:		update the flash information with the files in flash

 $Returns:		TRUE if OK, wrong is something failed => no stored file, and not possible to 
 				create a new one. Typically, this mean the flash is not formatted

 $Arguments:		UINT32, value of bt_enable flag. 1 if enabled.

*******************************************************************************/
BOOL mfw_bt_read_status( void )
{
	return mfw_bt_current_cfg.bt_enable;
}



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

 $Function:		mfw_bt_store_status

 $Description:		update the BT status in flash

 $Returns:		MFW_BT_SUCCESS if OK, wrong is something failed => no stored file, and not possible to 
 				create a new one. Typically, this mean the flash is not formatted

 $Arguments:		new BT status: TRUE if enabled, FALSE if disabled.

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_store_status( BOOL new_enable_status )
{
	mfw_bt_current_cfg.bt_enable = new_enable_status;
	if( mfw_bt_flash_store_cfg() != (int)EFFS_OK)
			return MFW_BT_FAIL;

	return MFW_BT_SUCCESS;
}

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

 $Function:		mfw_bt_read_visibility

 $Description:		read the discoverability setting

 $Returns:		discoverability setting => TRUE if visible, FALSE if hidden

 $Arguments:		None

*******************************************************************************/
BOOL mfw_bt_read_visibility( void )
{
	return mfw_bt_current_cfg.discoverable;
}

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

 $Function:		mfw_bt_store_visibility

 $Description:		store the discoverability setting

 $Returns:		MFW_BT_SUCCESS if OK, MFW_BT_FAIL is something failed 
 				=> no stored file, and not possible to 
 				create a new one. Typically, this mean the flash is not formatted

 $Arguments:		new discoverability setting: TRUE if visible, FALSE if hidden

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_store_visibility( BOOL new_visibility )
{
	mfw_bt_current_cfg.discoverable = new_visibility;
	if( mfw_bt_flash_store_cfg() != (int)EFFS_OK)
			return MFW_BT_FAIL;

	return MFW_BT_SUCCESS;
}

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

 $Function:		mfw_bt_read_local_name

 $Description:		read local BT name

 $Returns:		local BT name. Pointer to a the string in the local database => this has to 
 				be copied if needed for other things.

 $Arguments:		None

*******************************************************************************/
UINT8* mfw_bt_read_local_name( void )
{
	return (UINT8*) mfw_bt_current_cfg.local_device_name;
}

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

 $Function:		mfw_bt_store_local_name

 $Description:		update the local name in flash

 $Returns:		MFW_BT_SUCCESS if OK, MFW_BT_FAIL is something failed 
 				=> typically, this mean the flash is not formatted

 $Arguments:		new local name. This data is copied and not freed.

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_store_local_name( char* new_name )
{
	if( new_name == NULL )
		return MFW_BT_FAIL;
	mfwStrncpy(mfw_bt_current_cfg.local_device_name, new_name, MFW_BT_NAME_LENGTH);

	if( mfw_bt_flash_store_cfg() != (int)EFFS_OK)
			return MFW_BT_FAIL;

	return MFW_BT_SUCCESS;
}




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

 $Function:		mfw_bt_flash_store_device

 $Description:		stores peer device to NVRAM. If device not already in data base => add it. If
 				there, update its information. !!! It will overwrite existing information! Use
 				this function wisely!=> typically, call mfw_bt_flash_get_device_info before to
 				get the pointer of an existing device, or allocate memory for a new one.

 $Returns:		MFW_BT_DATA_BASE_FULL if data base full. MFW_BT_FAIL if not 
 				able to write in flash. Else, success.

 $Arguments:		pointer to a device descriptor. IF NOT ALREADY IN THE DATABASE, WILL BE
 				COPIED. IF ALREADY IN THE DATABASE, THE DATA IS NOT COPIED!

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_flash_store_device( T_MFW_BT_REM_DEVICE * p_rem_device)
{
    	UINT8 i;

	/* first verify if we already have the device in our list */
	for(i=0; i<MFW_BT_NUM_REM_DEVICE; i++)
	{
		if( memcmp(&mfw_bt_device_db[i].bd_addr[0], &p_rem_device->bd_addr[0], BD_ADDR_LEN) == 0)
			/* ok, we found our device */		
			break;
	}
	if(i == MFW_BT_NUM_REM_DEVICE)
	{
		/* we are here => our device is not yet known. */
		for(i=0; i<MFW_BT_NUM_REM_DEVICE; i++)
			if(!(mfw_bt_device_db[i].in_use))
				/* we just found an empty record, great. */
				break;
	}
	/* verify if the database is not full */
	if( i == MFW_BT_NUM_REM_DEVICE)
    		return MFW_BT_DATA_BASE_FULL;


	/* 	we are here. This means either we found our device in the DB, either we have an empty
		record to fill in with our new device ( typically into the inquiry data base ). So first verify
		if it's a know device. */
	if( p_rem_device != &mfw_bt_device_db[i])
	{
		/* it's a new record, so copy it in our local db */
		memcpy(&mfw_bt_device_db[i], p_rem_device, sizeof(T_MFW_BT_REM_DEVICE));
	}
	mfw_bt_device_db[i].in_use = TRUE;
	mfw_bt_device_db[i].is_new = FALSE;		



	/* update data base in nvram */
	if( mfw_bt_flash_store_db() != EFFS_OK )
		return MFW_BT_FAIL;
	return MFW_BT_SUCCESS;
}



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

 $Function:		mfw_bt_clean_inq_db

 $Description:		clean the contents of the inquiry data base in RAM. To be called before each
 				new inquiry.

 $Returns:		

 $Arguments:		

*******************************************************************************/
void mfw_bt_clean_inq_db( void )
{	
	UINT8 i;
	/*
	** CQ21834 : use the sizeof function to take into account any padding bytes which may have been added
	*/
	memset( (void*)mfw_bt_inq_db, 0,  sizeof(mfw_bt_inq_db));
	for( i=0;i<MFW_BT_NUM_REM_DEVICE; i++ ) 
		mfw_bt_inq_db[i].is_new = TRUE;
}



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

 $Function:		mfw_bt_add_inq_device

 $Description:		copy the information received into the RAM inquiry database. 

 $Returns:		T_MFW_BT_STATUS. MFW_BT_DATA_BASE_FULL or SUCCESS.

 $Arguments:		pointer to an inquiry result. Data is copied.

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_add_inq_device( T_MFW_BT_DM_INQ_RES* p_rem_device)
{
    	UINT8 i;

	/* first verify if we already have the device in our list */
	for(i=0; i<MFW_BT_NUM_REM_DEVICE; i++)
	{
		if(!(mfw_bt_inq_db[i].in_use))
		{
			/* we just found an empty record, great. */
			break;
		}
		else if (memcmp(&mfw_bt_inq_db[i].bd_addr, &p_rem_device->bd_addr, sizeof(BD_ADDR)) == 0)
		{
			/* we already know about this device ... just exit indicating SUCCESS */
			return MFW_BT_SUCCESS;
		}
	}
	
	/* verify if the database is not full */
	if(i == MFW_BT_NUM_REM_DEVICE)
    		return MFW_BT_DATA_BASE_FULL;	

	/* we found an unused device record. Update it */
	mfw_bt_inq_db[i].in_use = TRUE;
	memcpy(mfw_bt_inq_db[i].bd_addr, p_rem_device->bd_addr, BD_ADDR_LEN);
	memcpy(mfw_bt_inq_db[i].dev_class, p_rem_device->dev_class, BD_ADDR_LEN);
	return MFW_BT_SUCCESS;
	
}



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

 $Function:		mfw_bt_add_disc_device

 $Description:		copy the information received into the RAM inquiry database.  

 $Returns:		T_MFW_BT_STATUS. MFW_BT_DATA_BASE_FULL or SUCCESS.

 $Arguments:		pointer to a discovery result. Data is copied.

*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_add_disc_device( T_MFW_BT_DM_DISC_RES* p_rem_device)
{
    	UINT8 i;

	/* first verify if we already have the device in our list */
	for(i=0; i<MFW_BT_NUM_REM_DEVICE; i++)
	{
		if( memcmp(&mfw_bt_inq_db[i].bd_addr, &p_rem_device->bd_addr, sizeof(BD_ADDR)) == 0)
		{
				/* we just found an empty record, great. */
				break;
		}
	}

	/* verify if the database is not full */
	if(i == MFW_BT_NUM_REM_DEVICE)
    		return MFW_BT_DATA_BASE_FULL;

	/* now update the device with the new informations */
	mfwStrncpy((char*)mfw_bt_inq_db[i].name, (char*)p_rem_device->name, MFW_BT_NAME_LENGTH);
	/*
	** CQ21834 : Update the Friendly Name also.
	*/
	mfwStrncpy((char*)mfw_bt_inq_db[i].friendly_name, (char*)p_rem_device->name, MFW_BT_NAME_LENGTH);
	mfw_bt_inq_db[i].services = p_rem_device->services;

	return MFW_BT_SUCCESS;

}

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

 $Function:		mfw_bt_get_device_info

 $Description:		gets the device record of a stored device.  

 $Returns:		NULL if device not found. Pointer to a device structure if found. This data should
 				be copied if wanted to be used somewhere else.
 				If the device is not stored in Flash, the is_new flag is set => this means it is
 				a newly found device ( from an inquiry or discovery result ).

 $Arguments:		DB_ADDR of the device wanted.
 

*******************************************************************************/
T_MFW_BT_REM_DEVICE * mfw_bt_get_device_info(BD_ADDR bd_addr)
{
	UINT8 i;
	T_MFW_BT_REM_DEVICE *p_device;
	
	for(i=0; i<MFW_BT_NUM_REM_DEVICE; i++)
	{
		if (mfw_bt_device_db[i].in_use)
		{
			if(memcmp(&mfw_bt_device_db[i].bd_addr[0], &bd_addr[0], BD_ADDR_LEN) == 0)
			{
				return &mfw_bt_device_db[i];
			}
		}
	}

	/* we didn't find our device, look into the inquiry db */
	for(i=0; i<MFW_BT_NUM_REM_DEVICE; i++)
	{
		if (mfw_bt_inq_db[i].in_use)
		{
			if(memcmp(&mfw_bt_inq_db[i].bd_addr[0], &bd_addr[0], BD_ADDR_LEN) == 0)
			{
				return &mfw_bt_inq_db[i];
			}
		}
	}

	return NULL;

}


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

 $Function:		mfw_bt_get_device_by_service

 $Description:		gets a list of device records corresponding to the given service. If service = 0,
 				will return all the stored devices.

 $Returns:		T_MFW_BT_STATUS

 $Arguments:		services => mask of services to look for
 
 				pp_device: a pointer to a T_MFW_BT_REM_DEVICE[MFW_BT_NUM_REM_DEVICE]
 				array. THIS MEMORY HAVE TO BE ALLOCATED!!! This function will add the 
 				pointers one by one into this array!!! The pointers are pointing on local data =>
 				might need to be copied.
 				(Note ... The pointer pp_device is a pointer to an ARRAY OF POINTERS of type T_MFW_BT_REM_DEVICE,
 				ie declared in the calling function as T_MFW_BT_REM_DEVICE *ptr_device[MFW_BT_NUM_REM_DEVICE])

 				number_of_devices: will be used to return the number of devices matching
 				the service mask.
 				
*******************************************************************************/
void mfw_bt_get_device_by_service( T_MFW_BT_SERVICE_MASK services,
														T_MFW_BT_REM_DEVICE ** pp_device,
														UINT8*	number_of_devices )
{
	UINT8 i;

	*number_of_devices = 0;
	if( services == 0 )
		services = BTA_ALL_SERVICE_MASK;
	
	for(i=0; i<MFW_BT_NUM_REM_DEVICE; i++)
	{
		/*
		** CQ21834 : The entry in the known devices database is valid only if the 'in_use' flag is TRUE AND
		** 			the 'is_new' flag is FALSE.
		*/
		if ( ( mfw_bt_device_db[i].in_use == TRUE ) && (mfw_bt_device_db[i].is_new == FALSE))
		{
			if ( (mfw_bt_device_db[i].services & services) != 0 )
			{
				MFW_BT_TRACE_P1("mfw_bt_get_device_by_service(), Device %d is Active and matches the criteria", i);
				pp_device[(*number_of_devices)] = &mfw_bt_device_db[i];
				(*number_of_devices) ++;
			}
		}
	}
	return;
}



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

 $Function:		mfw_bt_flash_delete_device

 $Description:		deletes the device from nvram

 $Returns:		MFW_BT_FAIL, MFW_BT_SUCCESS, 
 				MFW_BT_UNKNOWN_DEVICE

 $Arguments:		BD_ADDR of the device to remove from flash.
 				
*******************************************************************************/
T_MFW_BT_STATUS mfw_bt_flash_delete_device(BD_ADDR bd_addr)
{
    UINT8 i;
	T_MFW_BT_STATUS status;
	T_MFW_BT_REM_DEVICE *p_device;

    for(i=0; i<MFW_BT_NUM_REM_DEVICE; i++)
    {
		if(memcmp(&mfw_bt_device_db[i].bd_addr[0], &bd_addr[0], BD_ADDR_LEN) == 0)
        {
			/*
			** CQ21834 : Erase the details from the Device Database and check whether the
			** device is in the Inquiry Database. If so, set the 'is_new' flag in the Inquiry Db
			** to TRUE to indicate that the device is 'not known'
			*/
			memset(&mfw_bt_device_db[i], 0x00, sizeof(T_MFW_BT_REM_DEVICE));

			status = mfw_bt_flash_store_device(&mfw_bt_device_db[i]);

			p_device = mfw_bt_get_device_info(bd_addr);

			if (p_device != NULL)
			{
				p_device->is_new = TRUE;
			}

			return status;

		}
	}

	return MFW_BT_UNKNOWN_DEVICE;
}




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

 $Function:		mfw_bt_flash_store_db

 $Description:		write the whole device data base in flash

 $Returns:		=0 if ok, <0 if error ( see ffs code )

 $Arguments:		none

*******************************************************************************/
static int mfw_bt_flash_store_db(void)
{ 
	effs_t    status;

	/*
	** CQ21834 : use the sizeof function to take into account any padding bytes which may have been added
	*/
	status = flash_data_write( MFW_BT_CFG_ROOT_PATH,
							MFW_BT_SEC_FILE,
							(void *)&mfw_bt_device_db,
							sizeof(mfw_bt_device_db));
	if ( status != EFFS_OK )
	{
	    /* mmh thats bad, well go with stored default config. */
	    MFW_BT_TRACE_P1(" mfw_bt_nv_init_device_db(): flash_data_write failed: %d", status );
	}

	return (int)status;
}



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

 $Function:		mfw_bt_flash_read_cfg

 $Description:		load the BT config from flash to RAM

 $Returns:		>0 if read ok, =0 if create default ok, <0 if error ( see ffs code )

 $Arguments:		none

*******************************************************************************/
static int mfw_bt_flash_read_cfg( void )
{
	int 	status;
	effs_t ffs_status;

	/* first, reset RAM-based config */
	memset(&mfw_bt_current_cfg,0x00,sizeof(mfw_bt_current_cfg));

	/* then read the one in flash */
	status = flash_data_read ( MFW_BT_CFG_ROOT_PATH,
							 MFW_BT_CFG_FILE, 
							 (void *)&mfw_bt_current_cfg, 
							 sizeof(tMFW_BT_CFG) );
	if( status <= 0)
	{
		/* no config file? => update the RAM settings with the default ones */
		mfw_bt_current_cfg.bt_enable = MFW_BT_ENABLED;
		mfw_bt_current_cfg.discoverable = MFW_BT_DISCOVERABLE_MODE;
		memset(&mfw_bt_current_cfg.local_device_name, 0x00, MFW_BT_NAME_LENGTH);

		/* then try to create one */
		MFW_BT_TRACE(" mfw_bt_read_cfg_file(): flash_data_read failed. Create default one.");
		ffs_status = flash_data_write(MFW_BT_CFG_ROOT_PATH,
								     MFW_BT_CFG_FILE,
		                                		     (void *)&mfw_bt_current_cfg,
		                                		     sizeof(tMFW_BT_CFG));
		if ( ffs_status != EFFS_OK )
		{
			/* mmh thats really bad! */
			MFW_BT_TRACE_P1(" mfw_bt_read_cfg_file(): flash_data_write failed: %d", ffs_status );
			status = (int)ffs_status;
		}
		else
			status = sizeof(tMFW_BT_CFG);
	}

	/* else, nothing to do: mfw_bt_current_cfg has already been updated */
	return status;
}
	



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

 $Function:		mfw_bt_flash_store_cfg

 $Description:		writes the cfg file in flash

 $Returns:		=0 if ok, <0 if error ( see ffs code )

 $Arguments:		none

*******************************************************************************/
static int mfw_bt_flash_store_cfg( void )
{
	effs_t 	status;

	status = flash_data_write(MFW_BT_CFG_ROOT_PATH,
							MFW_BT_CFG_FILE,
							(void *)&mfw_bt_current_cfg,
	                                		sizeof(mfw_bt_current_cfg));
	if ( status != EFFS_OK )
	{
		/* mmh thats really bad! */
		MFW_BT_TRACE_P1(" mfw_bt_store_cfg_file(): flash_data_write failed: %d", status );
	}

	/* else, nothing to do, just return */
	return (int)status;
}



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

 $Function:		mfw_bt_flash_read_db

 $Description:		load the device data base from flash to RAM

 $Returns:		>0 if read ok, =0 if create default ok, <0 if error ( see ffs code )

 $Arguments:		none

*******************************************************************************/
static int mfw_bt_flash_read_db(void)
{
	int status;
	effs_t ffs_status;

	/* Phone needs to store in nvram some information about other bluetooth devices 
	which it regularly communicates with. The information that has to be stored typically 
	are bdaddr, name, link_key, trust relationship etc.  */	
	MFW_BT_TRACE( "mfw_bt_flash_read_db()");
	
	/* first, reset RAM-based db */
	memset(&mfw_bt_device_db,0x00,sizeof(mfw_bt_device_db));

	/* try to read existing device database stored in nv-ram */
	status = flash_data_read( MFW_BT_CFG_ROOT_PATH,
							MFW_BT_SEC_FILE,
	                             		(void *)&mfw_bt_device_db,
	                             		sizeof(mfw_bt_device_db));

	if ( status <= 0 )
	{
		/* failed => the device db file doesn't exist. Create an empty one. */
		MFW_BT_TRACE(" mfw_bt_flash_read_db(): flash_data_read failed. Create one" );

		ffs_status = flash_data_write( MFW_BT_CFG_ROOT_PATH,
									MFW_BT_SEC_FILE,
									(void *)&mfw_bt_device_db,
									sizeof(mfw_bt_device_db));

		if ( ffs_status != EFFS_OK )
		{
		    /* mmh thats really bad, well go with stored default config. */
		    MFW_BT_TRACE_P1(" mfw_bt_flash_read_db(): flash_data_write failed: %d", ffs_status );
			status = (int)ffs_status;
		}
		else
			status = sizeof(tMFW_BT_CFG);
	}
	return status;
}