mirror of
https://github.com/apache/nuttx.git
synced 2026-08-04 22:00:21 +00:00
Our net socket connection allocations are powerful but redundant because they're implemented once in each protocol. This is not good for further optimizing and extending to other allocations, so maybe we can add a common implementation for the usage. Impact: 1. We add a `struct net_bufpool_s` as pool descriptor, which may use a little bit more memory than previous implementation (~28Bytes). 2. We share same functions between pools, so code size may shrink under some scenarios. Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
278 lines
7.8 KiB
C
278 lines
7.8 KiB
C
/****************************************************************************
|
|
* net/bluetooth/bluetooth_conn.c
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership. The
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <debug.h>
|
|
|
|
#include <netpacket/bluetooth.h>
|
|
#include <arch/irq.h>
|
|
|
|
#include <nuttx/kmalloc.h>
|
|
#include <nuttx/mm/iob.h>
|
|
#include <nuttx/net/netconfig.h>
|
|
#include <nuttx/net/net.h>
|
|
#include <nuttx/net/netdev.h>
|
|
#include <nuttx/net/bluetooth.h>
|
|
|
|
#include "devif/devif.h"
|
|
#include "utils/utils.h"
|
|
#include "bluetooth/bluetooth.h"
|
|
|
|
#ifdef CONFIG_NET_BLUETOOTH
|
|
|
|
/****************************************************************************
|
|
* Pre-processor Definitions
|
|
****************************************************************************/
|
|
|
|
#ifndef CONFIG_NET_BLUETOOTH_MAX_CONNS
|
|
# define CONFIG_NET_BLUETOOTH_MAX_CONNS 0
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Private Data
|
|
****************************************************************************/
|
|
|
|
/* The array containing all packet socket connections. Protected via the
|
|
* network lock.
|
|
*/
|
|
|
|
NET_BUFPOOL_DECLARE(g_bluetooth_connections, sizeof(struct bluetooth_conn_s),
|
|
CONFIG_NET_BLUETOOTH_PREALLOC_CONNS,
|
|
CONFIG_NET_BLUETOOTH_ALLOC_CONNS,
|
|
CONFIG_NET_BLUETOOTH_MAX_CONNS);
|
|
|
|
/* A list of all allocated packet socket connections */
|
|
|
|
static dq_queue_t g_active_bluetooth_connections;
|
|
|
|
static const bt_addr_t g_any_addr =
|
|
{
|
|
BT_ADDR_ANY
|
|
};
|
|
|
|
/****************************************************************************
|
|
* Public Functions
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: bluetooth_conn_initialize
|
|
*
|
|
* Description:
|
|
* Initialize the Bluetooth connection structure allocator. Called
|
|
* once and only from bluetooth_initialize().
|
|
*
|
|
* Assumptions:
|
|
* Called early in the initialization sequence
|
|
*
|
|
****************************************************************************/
|
|
|
|
void bluetooth_conn_initialize(void)
|
|
{
|
|
NET_BUFPOOL_INIT(g_bluetooth_connections);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: bluetooth_conn_alloc()
|
|
*
|
|
* Description:
|
|
* Allocate a new, uninitialized packet socket connection structure. This
|
|
* is normally something done by the implementation of the socket() API
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR struct bluetooth_conn_s *bluetooth_conn_alloc(void)
|
|
{
|
|
FAR struct bluetooth_conn_s *conn;
|
|
|
|
/* The free list is protected by the network lock */
|
|
|
|
net_lock();
|
|
|
|
conn = NET_BUFPOOL_TRYALLOC(g_bluetooth_connections);
|
|
if (conn)
|
|
{
|
|
/* Mark as unbound */
|
|
|
|
conn->bc_proto = BTPROTO_NONE;
|
|
|
|
/* Enqueue the connection into the active list */
|
|
|
|
dq_addlast(&conn->bc_conn.node, &g_active_bluetooth_connections);
|
|
}
|
|
|
|
net_unlock();
|
|
return conn;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: bluetooth_conn_free()
|
|
*
|
|
* Description:
|
|
* Free a packet socket connection structure that is no longer in use.
|
|
* This should be done by the implementation of close().
|
|
*
|
|
****************************************************************************/
|
|
|
|
void bluetooth_conn_free(FAR struct bluetooth_conn_s *conn)
|
|
{
|
|
FAR struct bluetooth_container_s *container;
|
|
FAR struct bluetooth_container_s *next;
|
|
|
|
/* The free list is protected by the network lock. */
|
|
|
|
DEBUGASSERT(conn->bc_crefs == 0);
|
|
|
|
/* Remove the connection from the active list */
|
|
|
|
net_lock();
|
|
dq_rem(&conn->bc_conn.node, &g_active_bluetooth_connections);
|
|
|
|
/* Check if there any any frames attached to the container */
|
|
|
|
for (container = conn->bc_rxhead; container != NULL; container = next)
|
|
{
|
|
/* Remove the frame from the list */
|
|
|
|
next = container->bn_flink;
|
|
container->bn_flink = NULL;
|
|
|
|
/* Free the contained frame data (should be only one in chain) */
|
|
|
|
if (container->bn_iob)
|
|
{
|
|
iob_free(container->bn_iob);
|
|
}
|
|
|
|
/* And free the container itself */
|
|
|
|
bluetooth_container_free(container);
|
|
}
|
|
|
|
/* Free the connection structure */
|
|
|
|
NET_BUFPOOL_FREE(g_bluetooth_connections, conn);
|
|
|
|
net_unlock();
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: bluetooth_conn_active()
|
|
*
|
|
* Description:
|
|
* Find a connection structure that is the appropriate
|
|
* connection to be used with the provided Bluetooth header
|
|
*
|
|
* Assumptions:
|
|
* This function is called from network logic at with the network locked.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR struct bluetooth_conn_s *
|
|
bluetooth_conn_active(FAR const struct bluetooth_frame_meta_s *meta)
|
|
{
|
|
FAR struct bluetooth_conn_s *conn;
|
|
|
|
DEBUGASSERT(meta != NULL);
|
|
|
|
for (conn =
|
|
(FAR struct bluetooth_conn_s *)g_active_bluetooth_connections.head;
|
|
conn != NULL;
|
|
conn = (FAR struct bluetooth_conn_s *)conn->bc_conn.node.flink)
|
|
{
|
|
/* match protocol and channel first */
|
|
|
|
if (meta->bm_proto != conn->bc_proto ||
|
|
meta->bm_channel != conn->bc_channel)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
switch (meta->bm_proto)
|
|
{
|
|
/* For BTPROTO_HCI, the socket will not be connected but only
|
|
* bound, thus we match for the device directly
|
|
*/
|
|
|
|
case BTPROTO_HCI:
|
|
|
|
/* TODO: handle when multiple devices supported, need to add ID
|
|
* to meta and conn structures
|
|
*/
|
|
|
|
goto stop;
|
|
|
|
break;
|
|
|
|
/* For BTPROTO_L2CAP, the destination address must match the
|
|
* bound address of the socket
|
|
*/
|
|
|
|
case BTPROTO_L2CAP:
|
|
if ((BLUETOOTH_ADDRCMP(&conn->bc_raddr, &meta->bm_raddr) ||
|
|
BLUETOOTH_ADDRCMP(&conn->bc_raddr, &g_any_addr)) &&
|
|
(meta->bm_channel == conn->bc_channel))
|
|
{
|
|
goto stop;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
stop:
|
|
return conn;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: bluetooth_conn_next()
|
|
*
|
|
* Description:
|
|
* Traverse the list of allocated packet connections
|
|
*
|
|
* Assumptions:
|
|
* This function is called from network logic at with the network locked.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR struct bluetooth_conn_s *
|
|
bluetooth_conn_next(FAR struct bluetooth_conn_s *conn)
|
|
{
|
|
if (!conn)
|
|
{
|
|
return (FAR struct bluetooth_conn_s *)
|
|
g_active_bluetooth_connections.head;
|
|
}
|
|
else
|
|
{
|
|
return (FAR struct bluetooth_conn_s *)conn->bc_conn.node.flink;
|
|
}
|
|
}
|
|
|
|
#endif /* CONFIG_NET_BLUETOOTH */
|