OSStatus bt_smartbridge_att_cache_release( bt_smartbridge_att_cache_t* cache )
{
    OSStatus            result;

    if ( att_cache_manager == NULL )
    {
        return MICO_BT_ATT_CACHE_UNINITIALISED;
    }

    /* Lock protection */
    result = mico_rtos_lock_mutex( &att_cache_manager->mutex );
    if ( result != MICO_BT_SUCCESS )
    {
        return result;
    }

    result = linked_list_remove_node( &att_cache_manager->used_list, &cache->node );
    if ( result == MICO_BT_SUCCESS )
    {
        /* Delete list and set data to NULL */
        mico_bt_smart_attribute_delete_list( &cache->attribute_list );
    }

    smartbridge_att_cache_return_to_free_list( cache );

    /* Unlock protection */
    mico_rtos_unlock_mutex( &att_cache_manager->mutex );

    return result;
}
wiced_result_t bt_smartbridge_att_cache_generate( const wiced_bt_smart_device_t* remote_device, uint16_t connection_handle, bt_smartbridge_att_cache_t** cache )
{
    bt_smartbridge_att_cache_t* new_cache = NULL;
    wiced_result_t              result;

    if ( cache == NULL )
    {
        return WICED_BT_BADARG;
    }

    if ( att_cache_manager == NULL )
    {
        return WICED_BT_ATT_CACHE_UNINITIALISED;
    }

    /* Cached attributes not found. Get a free instance and discover services */
    result = smartbridge_att_cache_get_free_cache( &new_cache );
    if ( result != WICED_BT_SUCCESS )
    {
        return result;
    }

    /* Copy remote device to cache */
    wiced_rtos_lock_mutex( &new_cache->mutex );
    memcpy( &new_cache->remote_device, remote_device, sizeof( new_cache->remote_device ) );
    new_cache->connection_handle = connection_handle;
    new_cache->is_discovering    = WICED_TRUE;
    wiced_rtos_unlock_mutex( &new_cache->mutex );

    /* Rediscover services */
    result = smartbridge_att_cache_discover_all( new_cache, new_cache->connection_handle );

    wiced_rtos_lock_mutex( &new_cache->mutex );
    new_cache->is_discovering = WICED_FALSE;
    wiced_rtos_unlock_mutex( &new_cache->mutex );

    if ( result == WICED_BT_SUCCESS )
    {
        result = smartbridge_att_cache_insert_to_used_list( new_cache );

        if ( result == WICED_SUCCESS )
        {
            *cache = new_cache;
        }
    }
    else
    {
        smartbridge_att_cache_return_to_free_list( new_cache );
    }

    return result;
}