/****************************************************************************
NAME
    UpgradeSavePSKeys  -  Save our PSKEYS

DESCRIPTION
    Save our PSKEYS into Persistent Storage.

    The existing contents of the key are read first. If they chance not to 
    exist the the value we do not control are set to 0x0000 (deemed safer 
    than panicking or using a marker such as 0xFACE)

    Note that the upgrade library initialisation has guaranteed that the 
    the pskeys fit within the 64 words allowed.
    
    Although not technically part of our API, safest if we allow for the 
    PSKEY to be longer than we use.
*/
void UpgradeSavePSKeys(void)
{
    uint16 keyCache[PSKEY_MAX_STORAGE_LENGTH];
    uint16 min_key_length = UpgradeCtxGet()->upgrade_library_pskeyoffset
                                    +UPGRADE_PRIVATE_PSKEY_USAGE_LENGTH_WORDS;

    /* Find out how long the PSKEY is */
    uint16 actualLength = PsRetrieve(UpgradeCtxGet()->upgrade_library_pskey,NULL,0);
    if (actualLength)
    {
        PsRetrieve(UpgradeCtxGet()->upgrade_library_pskey,keyCache,actualLength);
    }
    else
    {
        if (UpgradeCtxGet()->upgrade_library_pskeyoffset)
        {
            /* Initialise the portion of key before us */
            memset(keyCache,0x0000,sizeof(keyCache));
        }
        actualLength = min_key_length;
    }

    /* Correct for too short a key */
    if (actualLength < min_key_length)
    {
        actualLength = min_key_length;
    }

    memcpy(&keyCache[UpgradeCtxGet()->upgrade_library_pskeyoffset],UpgradeCtxGetPSKeys(),
                UPGRADE_PRIVATE_PSKEY_USAGE_LENGTH_WORDS*sizeof(uint16));
    PsStore(UpgradeCtxGet()->upgrade_library_pskey,keyCache,actualLength);
}
/****************************************************************************
NAME
	connectionAuthGetAttribute

FUNCTION
	This function is called to read the specified data from the specified 
	persistent store key.  The persistent store key is calulated from
	the specified base + the index of the specified device in TDL.

RETURNS
*/
void connectionAuthGetAttribute(Task appTask, uint16 ps_base, const bdaddr* bd_addr, uint16 size_psdata)
{
	/* Find device in the TDL */
	uint16 index = find_trusted_device(bd_addr);
	
    if (appTask)
	{
		/* Send a message back to the application task */
		MAKE_CL_MESSAGE_WITH_LEN(CL_SM_GET_ATTRIBUTE_CFM, size_psdata);
		message->status = fail;
		message->size_psdata = size_psdata;
		message->psdata[0] = 0;
	
		/* If an entry exists in the TDL for the specified device */
		if(index)
		{
			index--;
			if(size_psdata)
			{
				/* Read attribute data */
				if(PsRetrieve(ps_base + index, message->psdata, size_psdata))
				{
					message->status = success;
				}
			}
		}	
		MessageSend(appTask, CL_SM_GET_ATTRIBUTE_CFM, message);
	}
}
/****************************************************************************
NAME
	connectionAuthSendLinkKey

FUNCTION
	This function is called to send the link key of the specified device to the
	Bluestack Security Manager

*/
void connectionAuthSendLinkKey(const bdaddr* peer_bd_addr)
{
	uint16						rec;
    TrustedDeviceRecordType     record;
	
    MAKE_PRIM_T(DM_SM_LINK_KEY_REQUEST_RES);
	connectionConvertBdaddr_t(&prim->bd_addr, peer_bd_addr);

	/* Search for the device in the TDL */
	rec = find_trusted_device(peer_bd_addr);
	
    /* If the device is in the TDL */
	if(rec)
	{
		rec--;
		/* Get the link key */
		(void)PsRetrieve(TRUSTED_DEVICE_LIST_BASE + rec, &record, sizeof(TrustedDeviceRecordType));

		prim->valid = 1;
		memcpy(prim->key, record.link_key, SIZE_LINK_KEY);
	}
	else
	{
		/* Reject the request for a link key */
		prim->valid = 0;        
		memset(prim->key, 0, SIZE_LINK_KEY);
	}

	
	/* Send message to the Connection Manager */
	VmSendDmPrim(prim);
}
/****************************************************************************
NAME
	connectionAuthSetTrustLevel

FUNCTION
	This function is called to set the trust level of a device stored in the
    trusted device list.  The Blustack Security Manager is updated with the
    change.

RETURNS
	TRUE is record updated, otherwise FALSE
*/
uint16 connectionAuthSetTrustLevel(cl_dm_bt_version version, const bdaddr* peer_bd_addr, uint16 trusted)
{
    /* Holds the position of a device in the trusted device list (TDL) */
	uint16  rec = 0;
    TrustedDeviceRecordType record;
    
    /* Search for the device in the TDL */
	rec = find_trusted_device(peer_bd_addr);

	
	/* If the device is in the TDL */
	if(rec)
	{
		rec--;

		/* Read the record */
		(void)PsRetrieve(TRUSTED_DEVICE_LIST_BASE + rec, &record, sizeof(TrustedDeviceRecordType));

        /* Update the trust level */
        record.trusted = trusted;

        /* Store the record */
	    (void)PsStore(TRUSTED_DEVICE_LIST_BASE + rec, &record, sizeof(TrustedDeviceRecordType));

        /* Update Bluestack Security Manager Database */
        register_device(version, &record);
		
        /* Record updated */
        return TRUE;
    }

	
    /* Record for this device does not exist */
    return FALSE;
}
/****************************************************************************
NAME
	connectionAuthGetDevice

FUNCTION
	This function is called to add a trusted device to the persistent trusted 
	device list.  A flag indicating if the device was found is returned.
*/
uint16 connectionAuthGetDevice(const bdaddr *peer_bd_addr, cl_sm_link_key_type *link_key_type, uint8 *link_key, uint16 *trusted)
{
	uint16						rec;
	uint16						res = FALSE;
    TrustedDeviceRecordType     record;
    

	/* Search for the device in the TDL */
	rec = find_trusted_device(peer_bd_addr);

    /* If the device is in the TDL */
	if(rec)
	{
		rec--;
		/* Get the link key */
		(void)PsRetrieve(TRUSTED_DEVICE_LIST_BASE + rec, &record, sizeof(TrustedDeviceRecordType));
		res = TRUE;

		*trusted = record.trusted;
		*link_key_type = record.link_key_type;
		memcpy(link_key, record.link_key, SIZE_LINK_KEY);
	}
	
	return res;
}
/****************************************************************************

DESCRIPTION
	This function will delete an entry from the trusted device index
*/
static uint16 delete_from_trusted_device_index(uint16 order, uint16 noDevices)
{
    TrustedDeviceIndexType		tdi;
	uint16						index;
    uint16                      ok = FALSE;
	
	/* Read the TDI from persistent store */
	if(PsRetrieve(TRUSTED_DEVICE_INDEX, &tdi, sizeof(tdi)))
	{
		if(order != INDEX_INVALID)
		{
			/* Delete index from TDI and reorder TDI */
			for(index = order; index < (noDevices - 1); index++)
				tdi.order[index] = tdi.order[index+1];

            /* LRU index is now invalid */
            tdi.order[noDevices - 1] = 0;
		}
		
		/* Store persistently */
		(void)PsStore(TRUSTED_DEVICE_INDEX, &tdi, sizeof(tdi));

        ok = TRUE;
	}

	return ok;
}
/****************************************************************************
NAME
    UpgradeLoadPSStore  -  Load PSKEY on boot

DESCRIPTION
    Save the details of the PSKEY and offset that we were passed on 
    initialisation, and retrieve the current values of the key.

    In the unlikely event of the storage not being found, we initialise
    our storage to 0x00 rather than panicking.
*/
void UpgradeLoadPSStore(uint16 dataPskey,uint16 dataPskeyStart)
{
    union {
        uint16      keyCache[PSKEY_MAX_STORAGE_LENGTH];
        FSTAB_COPY  fstab;
        } stack_storage;
    uint16 lengthRead;

    UpgradeCtxGet()->upgrade_library_pskey = dataPskey;
    UpgradeCtxGet()->upgrade_library_pskeyoffset = dataPskeyStart;

    /* Worst case buffer is used, so confident we can read complete key 
     * if it exists. If we limited to what it should be, then a longer key
     * would not be read due to insufficient buffer
     * Need to zero buffer used as the cache is on the stack.
     */
    memset(stack_storage.keyCache,0,sizeof(stack_storage.keyCache));
    lengthRead = PsRetrieve(dataPskey,stack_storage.keyCache,PSKEY_MAX_STORAGE_LENGTH);
    if (lengthRead)
    {
        memcpy(UpgradeCtxGetPSKeys(),&stack_storage.keyCache[dataPskeyStart],
                UPGRADE_PRIVATE_PSKEY_USAGE_LENGTH_WORDS*sizeof(uint16));
    }
    else
    {
        memset(UpgradeCtxGetPSKeys(),0x0000,sizeof(UpgradeCtxGetPSKeys()) * sizeof(uint16));
    }

    /* Load the implementation FSTAB. */
    loadFstab(&stack_storage.fstab, ps_store_implementation);
}
Exemple #8
0
static void readPsPermanentPairing (bdaddr *bd_addr, uint16 *link_key, uint16 *link_key_status, sink_attributes *attributes)
{
    uint16 * ps_key;
    
    /* Allocate and zero buffer to hold PS key */
    ps_key = mallocPanic(BD_ADDR_SIZE + LINK_KEY_SIZE + ATTRIBUTES_SIZE + 1);
    memset(ps_key, 0, BD_ADDR_SIZE + LINK_KEY_SIZE + ATTRIBUTES_SIZE + 1);
    
    /* Attempt to obtain current pairing data */
    PsRetrieve(CONFIG_PERMANENT_PAIRING, ps_key, BD_ADDR_SIZE + LINK_KEY_SIZE + ATTRIBUTES_SIZE + 1);

    /* Return any requested fields */
    if (link_key_status)
    {
        *link_key_status = ps_key[STATUS_LOC];
    }
    
    if (bd_addr)
    {
        memcpy(bd_addr, &ps_key[BD_ADDR_LOC], BD_ADDR_SIZE);
    }
    
    if (link_key)
    {
        memcpy(link_key, &ps_key[LINK_KEY_LOC], LINK_KEY_SIZE);
    }
    
    if (attributes)
    {
        memcpy(attributes, &ps_key[ATTRIBUTES_LOC], ATTRIBUTES_SIZE);
    }
    
    free(ps_key);
}
Exemple #9
0
void configManagerSqifPartitionsInit( void )
{
    /* read currently free SQIF partitions */                          
    uint16 ret_len = 0;
    uint16 partition_data = 0;
 
    /* Read partition information from PS */
    ret_len = PsRetrieve(PSKEY_SQIF_PARTITIONS, &partition_data, sizeof(uint16));
     
    if(!ret_len)
    {            
        /* no key present - assume all partitions are in use */
        theSink.rundata->partitions_free = 0;
    }
    else
    {
        theSink.rundata->partitions_free = LOWORD(partition_data);
    }
    
    CONF_DEBUG(("CONF : Current SQIF partitions free 0x%x \n", theSink.rundata->partitions_free));
    
    /* Check that the currently selected languages partition is available */
    if((1<<theSink.tts_language) & theSink.rundata->partitions_free)
    {
        uint16 currentLang = theSink.tts_language;
        CONF_DEBUG(("CONF : Current SQIF VP partition (%u) not valid\n", currentLang));
        TTSSelectTTSLanguageMode();
        /* if the new selected language is the same then none could be found so disable TTS */
        if (currentLang == theSink.tts_language)
        {
            theSink.tts_enabled = FALSE;
            CONF_DEBUG(("CONF : Disabling TTS, no valid VP partitions\n"));
        }
    }
}
/****************************************************************************

DESCRIPTION
	This function will find the next free position in the Trusted Device List.

*/
static uint16 find_free_position(void)
{
	uint16						rec,index;
	TrustedDeviceIndexType		tdi;
	uint16						pos;
    TrustedDeviceRecordType     record;

	/* Loop through list of trusted devices */
	for(rec = 0; rec < NO_DEVICES_TO_MANAGE; rec++)
	{
		if(!PsRetrieve(TRUSTED_DEVICE_LIST_BASE + rec, &record, sizeof(TrustedDeviceRecordType)))
        {
			return (rec + 1);
        }
	}

	/* As the Trusted Device List is full then the position will be the
	   one occupied by the LRU device */
	(void)PsRetrieve(TRUSTED_DEVICE_INDEX, &tdi, sizeof(tdi));
	
	/* The LRU device is either the last device in the index or if empty (0) we
	   must traverse through the list to find the device */
	index = NO_DEVICES_TO_MANAGE;
	do
	{
		if(tdi.order[--index])
			break;
	}
	while(index);

	/* Record position */
	pos = tdi.order[index];
	
	if (PsRetrieve(TRUSTED_DEVICE_LIST_BASE + pos - 1, &record, sizeof(TrustedDeviceRecordType)))
		/* Remove from the BlueStack security datatbase */
		unregister_device(&record.bd_addr);

	/* Remove LRU device from the TDI */
	tdi.order[index] = 0; 
	(void)PsStore(TRUSTED_DEVICE_INDEX, &tdi, sizeof(tdi));	

	return pos;
}
/****************************************************************************
NAME
	connectionAuthGetAttribute

FUNCTION
	This function is called to read the specified data from the specified 
	persistent store key.  The persistent store key is calulated from
	the specified base + the index of the specified device in TDL.

RETURNS
*/
void connectionAuthGetIndexedAttribute(Task appTask, uint16 ps_base, uint16 mru_index, uint16 size_psdata)
{
	TrustedDeviceIndexType		tdi;
    TrustedDeviceRecordType     record;
	
	
	{
		/* Send a message back to the application task */
		MAKE_CL_MESSAGE_WITH_LEN(CL_SM_GET_INDEXED_ATTRIBUTE_CFM, size_psdata);
		message->status = fail;
		message->size_psdata = size_psdata;
		message->psdata[0] = 0;
		
		/* Read Trusted Device Index from Persistent store */
		if ((mru_index < MAX_TRUSTED_DEVICES) && PsRetrieve(TRUSTED_DEVICE_INDEX, &tdi, sizeof(tdi)))
		{
			/* Read the device record from the Trusted Device List */
			if (tdi.order[mru_index] && PsRetrieve((TRUSTED_DEVICE_LIST_BASE + tdi.order[mru_index] - 1), &record, sizeof(TrustedDeviceRecordType)))
			{
                /* Get Bluetooth address of device */
                message->bd_addr = record.bd_addr;
                
                /* Check if application wants attribute data */
				if (size_psdata != 0)
				{
					/* Read attribute data */
					if(PsRetrieve(ps_base + tdi.order[mru_index]-1, message->psdata, size_psdata))
						message->status = success;
				}
				else
				{
                    /* No attribute data required, so just indicate success */
					message->status = success;
				}
			}
		}

        /* Send confirmation back to application */
		MessageSend(appTask, CL_SM_GET_INDEXED_ATTRIBUTE_CFM, message);
	}
}
/****************************************************************************
NAME
	connectionAuthInit

FUNCTION
	This function is called to initialise the Trusted Device List.  All
	devices in the list are registered with the Bluestack Security Manager.

RETURNS
	The number of devices registered with Bluestack
*/
uint16 connectionAuthInit(cl_dm_bt_version version)
{
	uint16					registeredDevices = 0;
	TrustedDeviceIndexType	tdi;
	uint16					rec;
    TrustedDeviceRecordType record;
	
	/* Check if we have a valid Trusted Device Index */
	if(!PsRetrieve(TRUSTED_DEVICE_INDEX, &tdi, sizeof(tdi)))
	{
		/* Reset TDI to zero */
		memset(&tdi, 0, sizeof(TrustedDeviceIndexType));
		(void)PsStore(TRUSTED_DEVICE_INDEX, &tdi, sizeof(tdi));

		/* Delete TDL */
		for(rec = TRUSTED_DEVICE_LIST_BASE; rec <= TRUSTED_DEVICE_LIST_END; rec++)
			(void)PsStore(rec, NULL, 0);
	}
	else
	{
		/* Search through the Trusted Device List */
		for(rec = 0; rec < NO_DEVICES_TO_MANAGE; rec++)
		{
			/* For all devices in the list... */
			if(PsRetrieve(TRUSTED_DEVICE_LIST_BASE + rec, &record, sizeof(TrustedDeviceRecordType)))
			{
				
				/* Register the device with Bluestack Security Manager */
				register_device(version, &record);
				
				/* Keep a count of the number of active device records */
				registeredDevices++;
			}
		}
	}

	/* Return the number of devices registered with the Bluestack Security Manager */
	return registeredDevices;
}
Exemple #13
0
/****************************************************************************
NAME 
 	get_config_id

DESCRIPTION
 	This function is called to read the configuration ID
 
RETURNS
 	Defaults to config 0 if the key doesn't exist
*/
uint16 get_config_id(uint16 key)
{
 	/* Default to CSR standard configuration */
 	uint16 id = 0;
 
 	/* Read the configuration ID.  This identifies the configuration held in
       constant space */
 	if(PsRetrieve(key, &id, sizeof(uint16)))
 	{
  		if(id >= last_config_id)
  		{
   			id = 0;
  		}
 	}
 
 	return id;
}
/****************************************************************************

DESCRIPTION
	This function searches for the specified peer device in the Trusted Device 
	List (TDL). The value returned as position defines the record number of the
	device in TDL.

	 --------------------------------------
	|R1 | R2 | R3 | R4 | R5 | R6 | R7 | R8 |
	 --------------------------------------

	If the value returned is zero then the device does not exist in
	the TDL
*/
static uint16 find_trusted_device(const bdaddr* p_peer_addr)
{
	uint16						rec;
    TrustedDeviceRecordType     record;

	/* Loop through list of trusted devices */
	for(rec = 0; rec < NO_DEVICES_TO_MANAGE; rec++)
	{
		if(PsRetrieve(TRUSTED_DEVICE_LIST_BASE + rec, &record, sizeof(TrustedDeviceRecordType)))
		{
			/* If this device is already a trusted device? */
			if(BdaddrIsSame(&record.bd_addr, p_peer_addr))
				return (rec + 1);
		}
	}
	/* Device is not in the trusted device list */
	return 0;
}
/****************************************************************************
NAME
	connectionAuthDeleteAllDevices

FUNCTION
	This function is called to remove all trusted devices from the persistent 
    trusted device list.  A flag indicating if all the devices were successfully 
	removed is returned.
*/
uint16 connectionAuthDeleteAllDevice(uint16 ps_base)
{
	/* Flag to indicate if the devices were deleted */
    uint16      				deleted = FALSE;
	
	/* Trusted device list record index */
	uint16						rec = 0;
	
	/* Trusted device record */
	TrustedDeviceRecordType     record;
	
	/* trusted device index */
	TrustedDeviceIndexType		tdi;
	
	/* Loop through list of trusted devices */
	for(rec = 0; rec < NO_DEVICES_TO_MANAGE; rec++)
	{
		if(PsRetrieve(TRUSTED_DEVICE_LIST_BASE + rec, &record, sizeof(TrustedDeviceRecordType)))
		{
			/* Unregister with Bluestack security manager */
			unregister_device(&record.bd_addr);
			
			/* Delete entry from TDL */
			(void)PsStore(TRUSTED_DEVICE_LIST_BASE + rec, NULL, 0);

			deleted = TRUE;
		}

		/* Delete any associated attribute data */
		if(ps_base)
		{
			(void)PsStore(ps_base + rec, NULL, 0);
		}
	}
	
	/* Delete TDI */
	if(deleted)
	{
		memset(&tdi, 0, sizeof(TrustedDeviceIndexType));
		(void)PsStore(TRUSTED_DEVICE_INDEX, &tdi, sizeof(tdi));
	}
	
	return deleted;
}
/****************************************************************************
NAME    
    AuthGetPDLEntries
    
DESCRIPTION
    Returns the number of paired device list (PDL) entries

RETURNS
    bool 
*/
bool AuthGetPDLEntries(void)
{
	uint16 i;
	uint16 lNumDevices = 0;
	uint16 ltdi[sizeof(uint16) * MAX_PAIRED_DEVICES];
	
	if (PsRetrieve(41 , &ltdi , sizeof(uint16) * MAX_PAIRED_DEVICES))
 	{
		for (i = 0 ; i < MAX_PAIRED_DEVICES ; i ++)
    	{
    		if (ltdi[i] > lNumDevices )
    		{
    			lNumDevices = ltdi[i];
    		}
    	}
	}
	
	return lNumDevices;
}
/****************************************************************************

DESCRIPTION
	This function searches the Trusted Device Index (TDI) for a device 
	referenced by it's position in Trusted Device List (TDL).

	The TDI keeps a track of the order in which devices were connected
	too.  Each entry in the TDI holds a reference to a record
	in the TDL.  The TDI entries are ordered from Most Recently
	Used (MRU) to Least Recently Used (LRU)
	
	 --------------------------------------
	|Ra | Rb | Rc | Rd | Rd | Re | Rf | Rg |
	 --------------------------------------
	 ^									^
	 |									|
	 MRU								LRU
	
*/
static uint16 search_trusted_device_index(const uint16 pos)
{
	TrustedDeviceIndexType		tdi;
	uint16						offset = INDEX_INVALID;
	
	/* Read the TDI from persistent store */
	if(PsRetrieve(TRUSTED_DEVICE_INDEX, &tdi, sizeof(tdi)))
	{
		/* Loop through the TDI searching for an occurance of the device reference */
		for(offset = 0; offset < NO_DEVICES_TO_MANAGE; offset++)
		{
			/* If the required device is found in the TDI, return it's relative
			   position (offset) in the TDI */
			if(tdi.order[offset] == pos)
				break;
		}
	}

	return offset;
}
/****************************************************************************

DESCRIPTION
	This function updates the Trusted Device Index
*/
static void update_trusted_device_index(const uint16 position, const uint16 order)
{
	TrustedDeviceIndexType		tdi;
	uint16						index;
	
	/* Read the TDI from persistent store */
	if(PsRetrieve(TRUSTED_DEVICE_INDEX, &tdi, sizeof(tdi)))
	{
		if(order != INDEX_INVALID)
		{
			/* Re-order TDI */
			for(index = 0; index < order; index++)
				tdi.order[order - index] = tdi.order[(order - index) - 1];
		}
		
		/* Update with the position of the new record in the TDL as MRU device */
		tdi.order[0] = position;
		
		/* Store persistently */
		(void)PsStore(TRUSTED_DEVICE_INDEX, &tdi, sizeof(tdi));
	}
}
Exemple #19
0
static void writePsPermanentPairing (const bdaddr *bd_addr, uint16 *link_key, uint16 link_key_status, const sink_attributes *attributes)
{
    uint16 * ps_key;
    
    /* Allocate and zero buffer to hold PS key */
    ps_key = mallocPanic(BD_ADDR_SIZE + LINK_KEY_SIZE + ATTRIBUTES_SIZE + 1);
    memset(ps_key, 0, BD_ADDR_SIZE + LINK_KEY_SIZE + ATTRIBUTES_SIZE + 1);
    
    /* Attempt to obtain current pairing data */
    PsRetrieve(CONFIG_PERMANENT_PAIRING, ps_key, BD_ADDR_SIZE + LINK_KEY_SIZE + ATTRIBUTES_SIZE + 1);
    
    /* Update supplied fields */
    if (link_key_status)
    {
        ps_key[STATUS_LOC] = link_key_status;
    }
    
    if (bd_addr)
    {
        memcpy(&ps_key[BD_ADDR_LOC], bd_addr, BD_ADDR_SIZE);
    }
    
    if (link_key)
    {
        memcpy(&ps_key[LINK_KEY_LOC], link_key, LINK_KEY_SIZE);
    }
    
    if (attributes)
    {
        memcpy(&ps_key[ATTRIBUTES_LOC], attributes, ATTRIBUTES_SIZE);
    }
    
    /* Store updated pairing data */
    PsStore(CONFIG_PERMANENT_PAIRING, ps_key, BD_ADDR_SIZE + LINK_KEY_SIZE + ATTRIBUTES_SIZE + 1);
    
    free(ps_key);
}
/****************************************************************************
NAME
	connectionAuthSendSspLinkKey

FUNCTION
	This function is called to send the link key of the specified device to the
	Bluestack Security Manager in mode 4. In addition to the link key this also
	sends the link key type

*/
bool connectionAuthSendSspLinkKey(const bdaddr* peer_bd_addr, bool authenticated)
{
	uint16						rec;
    TrustedDeviceRecordType     record;
	bool 						success;
	uint8*						link_key;
	
    MAKE_PRIM_T(DM_SM_SSP_LINK_KEY_REQUEST_RES);
	connectionConvertBdaddr_t(&prim->bd_addr, peer_bd_addr);

	/* Search for the device in the TDL */
	rec = find_trusted_device(peer_bd_addr);
	
    /* If the device is in the TDL */
	if(rec)
	{
		rec--;
		/* Get the link key */
		(void)PsRetrieve(TRUSTED_DEVICE_LIST_BASE + rec, &record, sizeof(TrustedDeviceRecordType));

		/* Handle old records with no key type stored */
		if(record.link_key_type == 0)
			record.link_key_type = cl_sm_link_key_legacy;
		
		if(authenticated)
		{
			if(record.link_key_type == cl_sm_link_key_authenticated)
			{
				prim->key_type = connectionConvertLinkKeyType_t(record.link_key_type);
				link_key = (uint8*) PanicUnlessMalloc(SIZE_LINK_KEY);
				memcpy(link_key, record.link_key, SIZE_LINK_KEY);
				prim->key = VmGetHandleFromPointer(link_key);
				success = TRUE;
			}
			else
			{
				prim->key_type = connectionConvertLinkKeyType_t(cl_sm_link_key_none);
				prim->key = NULL;
				success = FALSE;
			}
		}
		else
		{
			prim->key_type = connectionConvertLinkKeyType_t(record.link_key_type);
			link_key = (uint8*) PanicUnlessMalloc(SIZE_LINK_KEY);
			memcpy(link_key, record.link_key, SIZE_LINK_KEY);
			prim->key = VmGetHandleFromPointer(link_key);
			success = TRUE;
		}
	}
	else
	{
		/* Reject the request for a link key */
		prim->key_type = connectionConvertLinkKeyType_t(cl_sm_link_key_none);
		prim->key = NULL;
		success = FALSE;
	}

	/* Send message to the Connection Manager */
	VmSendDmPrim(prim);
	
	return success;
}
Exemple #21
0
/****************************************************************************
NAME 
 	ConfigRetrieve

DESCRIPTION
 	This function is called to read a configuration key.  If the key exists
 	in persistent store it is read from there.  If it does not exist then
 	the default is read from constant space
 
RETURNS
 	0 if no data was read otherwise the length of data
*/
uint16 ConfigRetrieve(uint16 config_id, uint16 key_id, void* data, uint16 len)
{
 	uint16 ret_len;
 
 	/* Read requested key from PS if it exists */
 	ret_len = PsRetrieve(key_id, data, len);
     
 	/* If no key exists then read the parameters from the default configuration
       held in constant space */
 	if(!ret_len)
 	{
  		/* Access the required configuration */
  		if( default_configs[ config_id ] )
  		{  
            key_type * key;
            
            /* as the default configuration structures are aligned in key_id order
               it is safe to set the pointer such that it treats the default config
               config_type structure as an array and index that via the key_id value.

               The following line casts the default_config pointer to the first entry
               in the configuration structure which will be (key_type *)&battery_config, 
               the key_id (0 to 31) is then added to the start of the config to give the
               correct offset with the structure. Key then retrieves the .length and .data
               pointer from the configuration */
            key = *((key_type**)default_configs[config_id] + key_id);
            
            /* Providing the retrieved length is not zero. */
   			if(key->length == 0)
			{
				/* This will indicate an error. */
				ret_len = 0;
			}
			else
			{
	   			if(key->length == len)
	   			{
	    			/* Copy from constant space */
					memmove(data, &key->data, len);
	    			ret_len = len;
	   			}
	   			else
	   			{
					if(key->length > len)
					{
						DEBUG(("CONF:BADLEN![%x][%x][%x]\n",key_id, key->length, len)) ;	
						Panic() ;
					}
					else
					{
		   				/* (key.length < len) && (key.length != 0) here since we're comparing unsigned numbers. */

		   				/* We have more space than the size of the key in constant space.
		   				   Just copy the data for the key.
		   				   The length returned will let the caller know about the length mismatch. */
		    			/* Copy from constant space */
						memmove(data, &key->data, key->length);
		    			ret_len = key->length;
	    			}
	   			}
   			}
  		}
 	}
    else
    {
    	switch(key_id)
    	{
			/* PS keys where it's ok for (ret_len != len) */
    		case(PSKEY_CODEC_NEGOTIATION):
    			break;
            case(PSKEY_CONFIG_TONES):
                break;
    		default:
				if (ret_len != len)
				{
					DEBUG(("CONF:BADLEN![%x][%x][%x]\n",key_id, ret_len, len)) ;	
					Panic() ;
				}		 
    			break;
    	}
    }   
 
 	return ret_len;
}