FreeCalypso > hg > fc-magnetite
view src/aci2/mfw/mfw_bt_flash.c @ 673:62a5285e014a
Lorekeeping: allow tpudrv-leonardo.lib on Leonardo/Tango
Back in 2015 the Mother's idea was to produce a FreeCalypso development
board that would be a clone of TI Leonardo, including the original
quadband RFFE; one major additional stipulation was that this board
needed to be able to run original unmodified TCS211-20070608 firmware
with all blobs intact, with only minimal binary patches to main.lib
and tpudrv.lib. The necessary patched libs were produced at that time
in the tcs211-patches repository.
That plan was changed and we produced FCDEV3B instead, with Openmoko's
triband RFFE instead of Leonardo quadband, but when FC Magnetite started
in 2016, a TPUDRV_blob= provision was still made, allowing the possibility
of patching OM's tpudrv.lib for a restored Leonardo RFFE.
Now in 2020 we have FC Tango which is essentially a verbatim clone of
Leonardo core, including the original quadband RFFE. We have also
deblobbed our firmware so much that we have absolutely no real need
for a blob version of tpudrv.lib - but I thought it would be neat to put
the ancient TPUDRV_blob= mechanism (classic config) to its originally
intended use, just for the heck of it.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 29 May 2020 03:55:36 +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; }