Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
/*
* Copyright 2016-2024, Cypress Semiconductor Corporation (an Infineon company) or
* an affiliate of Cypress Semiconductor Corporation. All rights reserved.
*
* This software, including source code, documentation and related
* materials ("Software") is owned by Cypress Semiconductor Corporation
* or one of its affiliates ("Cypress") and is protected by and subject to
* worldwide patent protection (United States and foreign),
* United States copyright laws and international treaty provisions.
* Therefore, you may use this Software only as provided in the license
* agreement accompanying the software package from which you
* obtained this Software ("EULA").
* If no EULA applies, Cypress hereby grants you a personal, non-exclusive,
* non-transferable license to copy, modify, and compile the Software
* source code solely for use in connection with Cypress's
* integrated circuit products. Any reproduction, modification, translation,
* compilation, or representation of this Software except as specified
* above is prohibited without the express written permission of Cypress.
*
* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress
* reserves the right to make changes to the Software without notice. Cypress
* does not assume any liability arising out of the application or use of the
* Software or any product or circuit described in the Software. Cypress does
* not authorize its products for use in any products where a malfunction or
* failure of the Cypress product may reasonably be expected to result in
* significant property damage, injury or death ("High Risk Product"). By
* including Cypress's product in a High Risk Product, the manufacturer
* of such system or application assumes all risk of such use and in doing
* so agrees to indemnify Cypress against all liability.
*/
#include "wiced_memory.h"
#include "wiced_platform.h"
#include "wiced_bt_dev.h"
#include "wiced_bt_ble.h"
#include "wiced_bt_trace.h"
#include "string.h"
#include "wiced_transport.h"
#include "hci_control_api.h"
#define HCI_CONTROL_FIRST_VALID_NVRAM_ID 0x10
#define HCI_CONTROL_INVALID_NVRAM_ID 0x00
#define KEY_INFO_POOL_BUFFER_COUNT 10
typedef struct
{
void *p_next;
uint16_t nvram_id;
uint8_t chunk_len;
uint8_t data[1];
} hci_control_nvram_chunk_t;
hci_control_nvram_chunk_t *p_nvram_first = NULL;
extern wiced_bt_buffer_pool_t* p_key_info_pool;//Pool for storing the key info
extern uint8_t pairing_allowed;
/*
* Delete NVRAM function is called when host deletes NVRAM chunk from the persistent storage.
*/
void hci_control_delete_nvram( int nvram_id ,wiced_bool_t from_host)
{
hci_control_nvram_chunk_t *p1, *p2;
if ( p_nvram_first == NULL )
return;
/* Special case when need to remove the first chunk */
if ( ( p_nvram_first != NULL ) && ( p_nvram_first->nvram_id == nvram_id ) )
{
p1 = p_nvram_first;
if ( from_host && ( wiced_bt_dev_delete_bonded_device (p1->data) == WICED_ERROR ) )
{
WICED_BT_TRACE("ERROR: while Unbonding device \n");
}
else
{
p_nvram_first = (hci_control_nvram_chunk_t *)p_nvram_first->p_next;
wiced_bt_free_buffer( p1 );
}
return;
}
/* Go through the linked list of chunks */
for ( p1 = p_nvram_first; p1 != NULL; p1 = (hci_control_nvram_chunk_t *)p1->p_next )
{
p2 = (hci_control_nvram_chunk_t *)p1->p_next;
if ( ( p2 != NULL ) && ( p2->nvram_id == nvram_id ) )
{
if ( from_host && ( wiced_bt_dev_delete_bonded_device (p2->data) == WICED_ERROR ) )
{
WICED_BT_TRACE("ERROR: while Unbonding device \n");
}
else
{
p1->p_next = p2->p_next;
wiced_bt_free_buffer( p2 );
}
return;
}
}
}
/*
* Write NVRAM function is called to store information in the RAM. This can be called when
* stack requires persistent storage, for example to save link keys. In this case
* data is also formatted and send to the host for real NVRAM storage. The same function is
* called when host pushes NVRAM chunks during the startup. Parameter from_host in this
* case is set to FALSE indicating that data does not need to be forwarded.
*/
int hci_control_write_nvram( int nvram_id, int data_len, void *p_data, BOOLEAN from_host )
{
uint8_t tx_buf[257];
uint8_t *p = tx_buf;
hci_control_nvram_chunk_t *p1;
wiced_result_t result;
/* first check if this ID is being reused and release the memory chunk */
hci_control_delete_nvram( nvram_id ,WICED_FALSE);
WICED_BT_TRACE( "p_key_info_pool:0x%x\n", p_key_info_pool );
if ( ( p1 = ( hci_control_nvram_chunk_t * )wiced_bt_get_buffer_from_pool( p_key_info_pool ) ) == NULL )
{
WICED_BT_TRACE( "Failed to alloc:%d\n", data_len );
return ( 0 );
}
if ( wiced_bt_get_buffer_size( p1 ) < ( sizeof( hci_control_nvram_chunk_t ) + data_len - 1 ) )
{
WICED_BT_TRACE( "Insufficient buffer size, Buff Size %d, Len %d \n",
wiced_bt_get_buffer_size( p1 ), ( sizeof( hci_control_nvram_chunk_t ) + data_len - 1 ) );
wiced_bt_free_buffer( p1 );
return ( 0 );
}
p1->p_next = p_nvram_first;
p1->nvram_id = nvram_id;
p1->chunk_len = data_len;
memcpy( p1->data, p_data, data_len );
p_nvram_first = p1;
{
wiced_bt_device_link_keys_t * p_keys = ( wiced_bt_device_link_keys_t *) p_data;
#ifndef CYW20706A2
result = wiced_bt_dev_add_device_to_address_resolution_db( p_keys);
#else
result = wiced_bt_dev_add_device_to_address_resolution_db( p_keys, p_keys->key_data.ble_addr_type);
#endif
}
WICED_BT_TRACE("Updated Addr Resolution DB:%d\n", result );
/* If NVRAM chunk arrived from host, no need to send it back, otherwise send over transport */
if (!from_host)
{
*p++ = nvram_id & 0xff;
*p++ = (nvram_id >> 8) & 0xff;
memcpy(p, p_data, data_len);
wiced_transport_send_data( HCI_CONTROL_EVENT_NVRAM_DATA, tx_buf, ( int )( data_len + 2 ) );
}
return (data_len);
}
/*
* Find nvram_id of the NVRAM chunk with first bytes matching specified byte array
*/
int hci_control_find_nvram_id(uint8_t *p_data, int len)
{
hci_control_nvram_chunk_t *p1;
/* Go through the linked list of chunks */
for (p1 = p_nvram_first; p1 != NULL; p1 = (hci_control_nvram_chunk_t *)p1->p_next)
{
WICED_BT_TRACE( "find %B %B len:%d", p1->data, p_data, len );
if ( memcmp( p1->data, p_data, len ) == 0 )
{
return ( p1->nvram_id );
}
}
return HCI_CONTROL_INVALID_NVRAM_ID;
}
/*
* Read NVRAM actually finds the memory chunk in the RAM
*/
int hci_control_read_nvram( int nvram_id, void *p_data, int data_len )
{
hci_control_nvram_chunk_t *p1;
int data_read = 0;
/* Go through the linked list of chunks */
for ( p1 = p_nvram_first; p1 != NULL; p1 = p1->p_next )
{
if ( p1->nvram_id == nvram_id )
{
data_read = ( data_len < p1->chunk_len ) ? data_len : p1->chunk_len;
memcpy( p_data, p1->data, data_read );
break;
}
}
return ( data_read );
}
/*
* Allocate nvram_id to save new NVRAM chunk
*/
int hci_control_alloc_nvram_id( )
{
hci_control_nvram_chunk_t *p1 = p_nvram_first;
int nvram_id;
uint8_t allocated_key_pool_count;
/* Go through the linked list of chunks */
WICED_BT_TRACE ( "hci_control_alloc_nvram_id\n" );
for ( nvram_id = HCI_CONTROL_FIRST_VALID_NVRAM_ID; p1 != NULL; nvram_id++ )
{
allocated_key_pool_count = 1;
for ( p1 = p_nvram_first; p1 != NULL; p1 = (hci_control_nvram_chunk_t *)p1->p_next )
{
/* If the key buffer pool is becoming full, we need to notify the mcu and disable Pairing.
* The mcu will need to delete some nvram entries and enable pairing in order to
* pair with more devices */
allocated_key_pool_count++;
if ( ( allocated_key_pool_count == KEY_INFO_POOL_BUFFER_COUNT ) && ( pairing_allowed ) )
{
// Send Max Number of Paired Devices Reached event message
wiced_transport_send_data( HCI_CONTROL_EVENT_MAX_NUM_OF_PAIRED_DEVICES_REACHED, NULL, 0 );
pairing_allowed = WICED_FALSE;
wiced_bt_set_pairable_mode( pairing_allowed, 0 );
}
if ( p1->nvram_id == nvram_id )
{
/* this nvram_id is already used */
break;
}
}
if ( p1 == NULL )
{
break;
}
}
WICED_BT_TRACE ( "hci_control_alloc_nvram_id:%d\n", nvram_id );
return ( nvram_id );
}