Skip to content
......@@ -294,6 +294,7 @@ source "net/pkt/Kconfig"
source "net/local/Kconfig"
source "net/tcp/Kconfig"
source "net/udp/Kconfig"
source "net/bluetooth/Kconfig"
source "net/ieee802154/Kconfig"
source "net/icmp/Kconfig"
source "net/icmpv6/Kconfig"
......
############################################################################
# net/Makefile
#
# Copyright (C) 2007, 2008, 2011-2017 Gregory Nutt. All rights reserved.
# Copyright (C) 2007, 2008, 2011-2018 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
......@@ -68,6 +68,7 @@ include local/Make.defs
include tcp/Make.defs
include udp/Make.defs
include sixlowpan/Make.defs
include bluetooth/Make.defs
include ieee802154/Make.defs
include devif/Make.defs
include ipforward/Make.defs
......
......@@ -9,6 +9,7 @@ Directory Structure
`- net/
|
+- arp - Address resolution protocol (IPv4)
+- bluetooth - PF_BLUETOOTH socket interface
+- devif - Stack/device interface layer
+- icmp - Internet Control Message Protocol (IPv4)
+- icmpv6 - Internet Control Message Protocol (IPv6)
......@@ -28,7 +29,6 @@ Directory Structure
+- usrsock - User socket API for user-space networking stack
`- utils - Miscellaneous utility functions
+-------------------------------------------------------------------++------------------------+
| Application layer || usrsock daemon |
+-------------------------------------------------------------------++------------------------+
......
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
menu "Bluetooth socket support"
config NET_BLUETOOTH
bool "Bluetooth socket support"
default n
depends on WIRELESS_BLUETOOTH
select NETDEV_IOCTL
---help---
Enable support for raw, Bluetooth sockets.
Raw sockets allow receiving and transmitting Bluetooth radio
frames without a layer2 protocol such as 6LoWPAN in between. Frames
received are copied into a Bluetooth socket tap before they
enter the network. Frames written into a Bluetooth socket will
bypass the network altogether and will be sent directly to the
Bluetooth MAC network interface driver outgoing frame queue.
if NET_BLUETOOTH
config NET_BLUETOOTH_NCONNS
int "Max Bluetooth sockets"
default 4
config NET_BLUETOOTH_NCONTAINERS
int "Number of pre-allocated frame containers"
default 8
---help---
This specifies the total number of preallocated frame containers.
One must be allocated with each incoming frame.
config NET_BLUETOOTH_BACKLOG
int "Maximum frame backlog"
default 8
range 0 255
---help---
As frames are received, then are help in an RX queue. They remain
in the RX queue until application logic reads the queue frames. To
prevent overrun, the maximum backlog may be set to a nonzero value.
What the backlog of queue frames reaches that count, the olds frame
will be freed, preventing overrun at the cost of losing the oldest
frames.
NOTE: The special value of zero will disable all backlog checkes.
endif # NET_BLUETOOTH
endmenu # Bluetooth Socket Support
############################################################################
# net/bluetooth/Make.defs
#
# Copyright (C) 2018 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
# Packet socket support
ifeq ($(CONFIG_NET_BLUETOOTH),y)
# Initialization / resource managment
NET_CSRCS += bluetooth_initialize.c
NET_CSRCS += bluetooth_conn.c
NET_CSRCS += bluetooth_container.c
# Socket layer
SOCK_CSRCS += bluetooth_sockif.c
SOCK_CSRCS += bluetooth_sendto.c
SOCK_CSRCS += bluetooth_recvfrom.c
# Device interface
NET_CSRCS += bluetooth_input.c
NET_CSRCS += bluetooth_callback.c
NET_CSRCS += bluetooth_poll.c
NET_CSRCS += bluetooth_finddev.c
# Include packet socket build support
DEPPATH += --dep-path bluetooth
VPATH += :bluetooth
endif # CONFIG_NET_BLUETOOTH
/****************************************************************************
* net/bluetooth/bluetooth.h
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef _NET_BLUETOOTH_BLUETOOTH_H
#define _NET_BLUETOOTH_BLUETOOTH_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <queue.h>
#include <nuttx/wireless/bt_hci.h>
#ifdef CONFIG_NET_BLUETOOTH
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Allocate a new Bluetooth socket data callback */
#define bluetooth_callback_alloc(dev,conn) \
devif_callback_alloc(dev, &conn->list)
#define bluetooth_callback_free(dev,conn,cb) \
devif_conn_callback_free(dev, cb, &conn->list)
/* Memory Pools */
#define BLUETOOTH_POOL_PREALLOCATED 0
#define BLUETOOTH_POOL_DYNAMIC 1
/****************************************************************************
* Public Type Definitions
****************************************************************************/
/* Used for containing and queuing IOBs along with information about the
* source of the frame.
*/
struct iob_s; /* Forward reference */
struct bluetooth_container_s
{
FAR struct bluetooth_container_s *bn_flink; /* Supports a singly linked list */
FAR struct iob_s *bn_iob; /* Contained IOB */
bt_addr_t bn_raddr; /* Source address of the packet */
uint8_t bn_channel; /* Source channel of the packet */
uint8_t bn_pool; /* See BLUETOOTH_POOL_* definitions */
};
/* Representation of a Bluetooth socket connection */
struct devif_callback_s; /* Forward reference */
struct bluetooth_conn_s
{
dq_entry_t bc_node; /* Supports a double linked list */
bt_addr_t bc_laddr; /* Locally bound / source address.
* Necessary only to support multiple
* Bluetooth devices */
bt_addr_t bc_raddr; /* Connected remote address */
uint8_t bc_channel; /* Connection channel */
uint8_t bc_crefs; /* Reference counts on this instance */
#if CONFIG_NET_BLUETOOTH_BACKLOG > 0
uint8_t bc_backlog; /* Number of frames in RX queue */
#endif
/* Queue of incoming packets */
FAR struct bluetooth_container_s *bc_rxhead;
FAR struct bluetooth_container_s *bc_rxtail;
/* This is a list of Bluetooth callbacks. Each callback represents
* a thread that is stalled, waiting for a device-specific event.
*/
FAR struct devif_callback_s *list;
};
/****************************************************************************
* Public Data
****************************************************************************/
#ifdef __cplusplus
# define EXTERN extern "C"
extern "C"
{
#else
# define EXTERN extern
#endif
/* The Bluetooth socket interface */
EXTERN const struct sock_intf_s g_bluetooth_sockif;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
struct bluetooth_frame_meta_s; /* Forward reference */
struct radio_driver_s; /* Forward reference */
struct net_driver_s; /* Forward reference */
struct socket; /* Forward reference */
struct sockaddr; /* Forward reference */
/****************************************************************************
* Name: bluetooth_initialize()
*
* Description:
* Initialize the Bluetooth socket support. Called once and only
* from the network initialization logic.
*
* Assumptions:
* Called early in the initialization sequence
*
****************************************************************************/
void bluetooth_initialize(void);
/****************************************************************************
* 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);
/****************************************************************************
* Name: bluetooth_conn_alloc()
*
* Description:
* Allocate a new, uninitialized Bluetooth socket connection
* structure. This is normally something done by the implementation of
* the socket() API
*
****************************************************************************/
FAR struct bluetooth_conn_s *bluetooth_conn_alloc(void);
/****************************************************************************
* Name: bluetooth_conn_free()
*
* Description:
* Free a Bluetooth 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);
/****************************************************************************
* Name: bluetooth_conn_active()
*
* Description:
* Find a connection structure that is the appropriate
* connection to be used with the provided Ethernet 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);
/****************************************************************************
* Name: bluetooth_conn_next()
*
* Description:
* Traverse the list of allocated Bluetooth 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);
/****************************************************************************
* Name: bluetooth_input
*
* Description:
* Handle incoming Bluetooth input
*
* This function is called when the radio device driver has received an
* frame from the network. The frame from the device driver must be
* provided in by the IOB frame argument of the function call:
*
* - The frame data is in the IOB io_data[] buffer,
* - The length of the frame is in the IOB io_len field, and
* - The offset past and radio MAC header is provided in the io_offset
* field.
*
* The frame argument may refer to a single frame (a list of length one)
* or may it be the head of a list of multiple frames.
*
* - The io_flink field points to the next frame in the list (if enable)
* - The last frame in the list will have io_flink == NULL.
*
* Input Parameters:
* radio The radio network driver interface.
* framelist - The head of an incoming list of frames. Normally this
* would be a single frame. A list may be provided if
* appropriate, however.
* meta - Meta data characterizing the received frame.
*
* If there are multiple frames in the list, this metadata
* must apply to all of the frames in the list.
*
* Returned Value:
* OK The Bluetooth has been processed and can be deleted
* ERROR Hold the Bluetooth and try again later. There is a listening
* socket but no recv in place to catch the Bluetooth yet.
* Useful when a packet arrives before a recv call is in place.
*
* Assumptions:
* Called from the network diver with the network locked.
*
****************************************************************************/
/* bluetooth_input() is prototyped in include/nuttx/net/bluetooth.h */
/****************************************************************************
* Name: bluetooth_callback
*
* Description:
* Inform the application holding the Bluetooth socket of a change in state.
*
* Returned Value:
* OK if Bluetooth has been processed, otherwise ERROR.
*
* Assumptions:
* This function is called from network logic at with the network locked.
*
****************************************************************************/
uint16_t bluetooth_callback(FAR struct radio_driver_s *radio,
FAR struct bluetooth_conn_s *conn,
uint16_t flags);
/****************************************************************************
* Name: bluetooth_recvfrom
*
* Description:
* Implements the socket recvfrom interface for the case of the AF_INET
* and AF_INET6 address families. bluetooth_recvfrom() receives messages from
* a socket, and may be used to receive data on a socket whether or not it
* is connection-oriented.
*
* If 'from' is not NULL, and the underlying protocol provides the source
* address, this source address is filled in. The argument 'fromlen' is
* initialized to the size of the buffer associated with from, and
* modified on return to indicate the actual size of the address stored
* there.
*
* Input Parameters:
* psock A pointer to a NuttX-specific, internal socket structure
* buf Buffer to receive data
* len Length of buffer
* flags Receive flags
* from Address of source (may be NULL)
* fromlen The length of the address structure
*
* Returned Value:
* On success, returns the number of characters received. If no data is
* available to be received and the peer has performed an orderly shutdown,
* recv() will return 0. Otherwise, on errors, a negated errno value is
* returned (see recvfrom() for the list of appropriate error values).
*
****************************************************************************/
ssize_t bluetooth_recvfrom(FAR struct socket *psock, FAR void *buf,
size_t len, int flags, FAR struct sockaddr *from,
FAR socklen_t *fromlen);
/****************************************************************************
* Name: bluetooth_find_device
*
* Description:
* Select the network driver to use with the Bluetooth transaction.
*
* Input Parameters:
* conn - Bluetooth connection structure (not currently used).
* addr - The address to match the devices assigned address
*
* Returned Value:
* A pointer to the network driver to use. NULL is returned on any
* failure.
*
****************************************************************************/
FAR struct radio_driver_s *
bluetooth_find_device(FAR struct bluetooth_conn_s *conn,
FAR const bt_addr_t *addr);
/****************************************************************************
* Name: bluetooth_poll
*
* Description:
* Poll a Bluetooth "connection" structure for availability of TX data
*
* Input Parameters:
* dev - The device driver structure to use in the send operation
* conn - The Bluetooth "connection" to poll for TX data
*
* Returned Value:
* None
*
* Assumptions:
* Called from the network device interface (devif) with the network
* locked.
*
****************************************************************************/
void bluetooth_poll(FAR struct net_driver_s *dev,
FAR struct bluetooth_conn_s *conn);
/****************************************************************************
* Name: psock_bluetooth_sendto
*
* Description:
* If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET)
* socket, the parameters to and 'tolen' are ignored (and the error EISCONN
* may be returned when they are not NULL and 0), and the error ENOTCONN is
* returned when the socket was not actually connected.
*
* Input Parameters:
* psock A pointer to a NuttX-specific, internal socket structure
* buf Data to send
* len Length of data to send
* flags Send flags
* to Address of recipient
* tolen The length of the address structure
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* a negated errno value is retruend. See sendto() for the complete list
* of return values.
*
****************************************************************************/
ssize_t psock_bluetooth_sendto(FAR struct socket *psock,
FAR const void *buf,
size_t len, int flags,
FAR const struct sockaddr *to, socklen_t tolen);
/****************************************************************************
* Name: bluetooth_container_initialize
*
* Description:
* This function initializes the container allocator. This function must
* be called early in the initialization sequence before any socket
* activity.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions:
* Called early in the initialization sequence
*
****************************************************************************/
void bluetooth_container_initialize(void);
/****************************************************************************
* Name: bluetooth_container_allocate
*
* Description:
* The bluetooth_container_allocate function will get a free continer
* for use by the recvfrom() logic.
*
* This function will first attempt to allocate from the g_free_container
* list. If that the list is empty, then the meta-data structure will be
* allocated from the dynamic memory pool.
*
* Input Parameters:
* None
*
* Returned Value:
* A reference to the allocated container structure. All user fields in this
* structure have been zeroed. On a failure to allocate, NULL is
* returned.
*
* Assumptions:
* The caller has locked the network.
*
****************************************************************************/
FAR struct bluetooth_container_s *bluetooth_container_allocate(void);
/****************************************************************************
* Name: bluetooth_container_free
*
* Description:
* The bluetooth_container_free function will return a container structure
* to the free list of containers if it was a pre-allocated container
* structure. If the container structure was allocated dynamically it will
* be deallocated.
*
* Input Parameters:
* container - container structure to free
*
* Returned Value:
* None
*
* Assumptions:
* The caller has locked the network.
*
****************************************************************************/
void bluetooth_container_free(FAR struct bluetooth_container_s *container);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* CONFIG_NET_BLUETOOTH */
#endif /* _NET_BLUETOOTH_BLUETOOTH_H */
/****************************************************************************
* net/bluetooth/bluetooth_callback.c
* Forward events to waiting PF_BLUETOOTH sockets.
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <debug.h>
#include <nuttx/mm/iob.h>
#include <nuttx/net/radiodev.h>
#include <nuttx/net/bluetooth.h>
#include "devif/devif.h"
#include "bluetooth/bluetooth.h"
#ifdef CONFIG_NET_BLUETOOTH
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: bluetooth_callback
*
* Description:
* Inform the application holding the packet socket of a change in state.
*
* Returned Value:
* OK if packet has been processed, otherwise ERROR.
*
* Assumptions:
* This function is called at the interrupt level with interrupts disabled.
*
****************************************************************************/
uint16_t bluetooth_callback(FAR struct radio_driver_s *radio,
FAR struct bluetooth_conn_s *conn,
uint16_t flags)
{
ninfo("flags: %04x\n", flags);
/* Some sanity checking */
if (conn != NULL)
{
/* Perform the callback */
flags = devif_conn_event(&radio->r_dev, conn, flags, conn->list);
}
return flags;
}
#endif /* CONFIG_NET_BLUETOOTH */
/****************************************************************************
* net/bluetooth/bluetooth_conn.c
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <semaphore.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <netpacket/bluetooth.h>
#include <arch/irq.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 "bluetooth/bluetooth.h"
#ifdef CONFIG_NET_BLUETOOTH
/****************************************************************************
* Private Data
****************************************************************************/
/* The array containing all packet socket connections. Protected via the
* network lock.
*/
static struct bluetooth_conn_s
g_bluetooth_connections[CONFIG_NET_BLUETOOTH_NCONNS];
/* A list of all free packet socket connections */
static dq_queue_t g_free_bluetooth_connections;
/* 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)
{
int i;
/* Initialize the queues */
dq_init(&g_free_bluetooth_connections);
dq_init(&g_active_bluetooth_connections);
for (i = 0; i < CONFIG_NET_BLUETOOTH_NCONNS; i++)
{
/* Link each pre-allocated connection structure into the free list. */
dq_addlast(&g_bluetooth_connections[i].bc_node,
&g_free_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 only accessed from user, non-interrupt level and
* is protected by a semaphore (that behaves like a mutex).
*/
net_lock();
conn = (FAR struct bluetooth_conn_s *)
dq_remfirst(&g_free_bluetooth_connections);
if (conn)
{
/* Enqueue the connection into the active list */
memset(conn, 0, sizeof(struct bluetooth_conn_s));
dq_addlast(&conn->bc_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 only accessed from user, non-interrupt level and
* is protected by a semaphore (that behaves like a mutex).
*/
DEBUGASSERT(conn->bc_crefs == 0);
/* Remove the connection from the active list */
net_lock();
dq_rem(&conn->bc_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 */
dq_addlast(&conn->bc_node, &g_free_bluetooth_connections);
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_node.flink)
{
/* Does the destination address match the bound address of the socket. */
if ((BLUETOOTH_ADDRCMP(&conn->bc_raddr, &meta->bm_raddr) ||
BLUETOOTH_ADDRCMP(&conn->bc_raddr, &g_any_addr)) &&
(meta->bm_channel == conn->bc_channel ||
BT_CHANNEL_ANY == conn->bc_channel))
{
continue;
}
}
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_node.flink;
}
}
#endif /* CONFIG_NET_BLUETOOTH */
/****************************************************************************
* net/bluetooth/bluetooth_container.c
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <semaphore.h>
#include <assert.h>
#include <errno.h>
#include <nuttx/kmalloc.h>
#include <nuttx/mm/iob.h>
#include "bluetooth/bluetooth.h"
/****************************************************************************
* Private Data
****************************************************************************/
/* The g_free_container is a list of IOB container structures that are
* available for general use. The number of messages in this list is a
* system configuration item.
*
* Mutually exclusive access to this list is managed via the network lock:
* i.e., the network must be locked beffore accessing this free list.
*/
static FAR struct bluetooth_container_s *g_free_container;
/* Pool of pre-allocated meta-data stuctures */
static struct bluetooth_container_s
g_container_pool[CONFIG_NET_BLUETOOTH_NCONTAINERS];
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: bluetooth_container_initialize
*
* Description:
* This function initializes the container allocator. This function must
* be called early in the initialization sequence before any socket
* activity.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions:
* Called early in the initialization sequence
*
****************************************************************************/
void bluetooth_container_initialize(void)
{
FAR struct bluetooth_container_s *container;
int i;
/* Initialize g_free_container, the list of meta-data structures that
* are available for allocation.
*/
g_free_container = NULL;
for (i = 0, container = g_container_pool;
i < CONFIG_NET_BLUETOOTH_NCONTAINERS;
i++, container++)
{
/* Add the next meta data structure from the pool to the list of
* general structures.
*/
container->bn_flink = g_free_container;
g_free_container = container;
}
}
/****************************************************************************
* Name: bluetooth_container_allocate
*
* Description:
* The bluetooth_container_allocate function will get a free continer
* for use by the recvfrom() logic.
*
* This function will first attempt to allocate from the g_free_container
* list. If that the list is empty, then the meta-data structure will be
* allocated from the dynamic memory pool.
*
* Input Parameters:
* None
*
* Returned Value:
* A reference to the allocated container structure. All user fields in this
* structure have been zeroed. On a failure to allocate, NULL is
* returned.
*
* Assumptions:
* The caller has locked the network.
*
****************************************************************************/
FAR struct bluetooth_container_s *bluetooth_container_allocate(void)
{
FAR struct bluetooth_container_s *container;
uint8_t pool;
/* Try the free list first */
net_lock();
if (g_free_container != NULL)
{
container = g_free_container;
g_free_container = container->bn_flink;
pool = BLUETOOTH_POOL_PREALLOCATED;
net_unlock();
}
else
{
net_unlock();
container = (FAR struct bluetooth_container_s *)
kmm_malloc((sizeof (struct bluetooth_container_s)));
pool = BLUETOOTH_POOL_DYNAMIC;
}
/* We have successfully allocated memory from some source? */
if (container != NULL)
{
/* Zero and tag the allocated meta-data structure. */
memset(container, 0, sizeof(struct bluetooth_container_s));
container->bn_pool = pool;
}
return container;
}
/****************************************************************************
* Name: bluetooth_container_free
*
* Description:
* The bluetooth_container_free function will return a container structure
* to the free list of containers if it was a pre-allocated container
* structure. If the container structure was allocated dynamically it will
* be deallocated.
*
* Input Parameters:
* container - container structure to free
*
* Returned Value:
* None
*
* Assumptions:
* The caller has locked the network.
*
****************************************************************************/
void bluetooth_container_free(FAR struct bluetooth_container_s *container)
{
/* If this is a pre-allocated meta-data structure, then just put it back
* in the free list.
*/
net_lock();
if (container->bn_pool == BLUETOOTH_POOL_PREALLOCATED)
{
container->bn_flink = g_free_container;
g_free_container = container;
net_unlock();
}
else
{
DEBUGASSERT(container->bn_pool == BLUETOOTH_POOL_DYNAMIC);
/* Otherwise, deallocate it. */
net_unlock();
sched_kfree(container);
}
}
/****************************************************************************
* net/bluetooth/bluetooth_finddev.c
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <nuttx/net/net.h>
#include <nuttx/net/radiodev.h>
#include <nuttx/net/bluetooth.h>
#include <nuttx/wireless/bt_hci.h>
#include "netdev/netdev.h"
#include "bluetooth/bluetooth.h"
#ifdef CONFIG_NET_BLUETOOTH
/****************************************************************************
* Private Types
****************************************************************************/
struct bluetooth_finddev_s
{
FAR const bt_addr_t *bf_addr;
FAR struct radio_driver_s *bf_radio;
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: bluetooth_dev_callback
*
* Description:
* Check if this device matches the connections local address.
*
* Input Parameters:
* dev - The next network device in the enumeration
*
* Returned Value:
* 0 if there is no match (meaning to continue looking); 1 if there is a
* match (meaning to stop the search).
*
****************************************************************************/
static int bluetooth_dev_callback(FAR struct net_driver_s *dev, FAR void *arg)
{
FAR struct bluetooth_finddev_s *match =
(FAR struct bluetooth_finddev_s *)arg;
DEBUGASSERT(dev != NULL && match != NULL && match->bf_addr != NULL);
/* First, check if this network device is an Bluetooth radio and that
* it has an assigned Bluetooth address.
*/
if (dev->d_lltype == NET_LL_BLUETOOTH && dev->d_mac.radio.nv_addrlen > 0)
{
DEBUGASSERT(dev->d_mac.radio.nv_addrlen == BLUETOOTH_ADDRSIZE);
/* Does the device address match */
if (BLUETOOTH_ADDRCMP(dev->d_mac.radio.nv_addr, match->bf_addr))
{
/* Yes.. save the match and return 1 to stop the search */
match->bf_radio = (FAR struct radio_driver_s *)dev;
return 1;
}
}
/* Keep looking */
return 0;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: bluetooth_find_device
*
* Description:
* Select the network driver to use with the Bluetooth transaction.
*
* Input Parameters:
* conn - Bluetooth connection structure (not currently used).
* addr - The address to match the devices assigned address
*
* Returned Value:
* A pointer to the network driver to use. NULL is returned on any
* failure.
*
****************************************************************************/
FAR struct radio_driver_s *
bluetooth_find_device(FAR struct bluetooth_conn_s *conn,
FAR const bt_addr_t *addr)
{
struct bluetooth_finddev_s match;
int ret;
DEBUGASSERT(conn != NULL);
match.bf_addr = addr;
match.bf_radio = NULL;
/* Search for the Bluetooth network device whose MAC is equal to the
* sockets bound local address.
*/
ret = netdev_foreach(bluetooth_dev_callback, (FAR void *)&match);
if (ret == 1)
{
DEBUGASSERT(match.bf_radio != NULL);
return match.bf_radio;
}
return NULL;
}
#endif /* CONFIG_NET_BLUETOOTH */
/****************************************************************************
* net/bluetooth/bluetooth_initialize.c
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "bluetooth/bluetooth.h"
#ifdef CONFIG_NET_BLUETOOTH
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: bluetooth_initialize()
*
* Description:
* Initialize the Bluetooth socket support. Called once and only
* from the network initialization logic.
*
* Assumptions:
* Called early in the initialization sequence
*
****************************************************************************/
void bluetooth_initialize(void)
{
/* Initialize connection structions */
bluetooth_conn_initialize();
/* Initialize the container allocator */
bluetooth_container_initialize();
}
#endif /* CONFIG_NET_BLUETOOTH */
/****************************************************************************
* net/bluetooth/bluetooth_input.c
* Handle incoming Bluetooth frame input
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/mm/iob.h>
#include <nuttx/net/radiodev.h>
#include <nuttx/net/bluetooth.h>
#include <nuttx/wireless/bt_hci.h>
#include "devif/devif.h"
#include "bluetooth/bluetooth.h"
#ifdef CONFIG_NET_BLUETOOTH
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: bluetooth_count_frames
*
* Description:
* Return the number of frames in the RX queue.
*
* Input Parameters:
* conn - The socket connection structure.
*
* Returned Value:
* The number of frames in the queue.
*
****************************************************************************/
#if defined(CONFIG_DEBUG_ASSERTIONS) && CONFIG_NET_BLUETOOTH_BACKLOG > 0
static int bluetooth_count_frames(FAR struct bluetooth_conn_s *conn)
{
FAR struct bluetooth_container_s *container;
int count;
for (count = 0, container = conn->bc_rxhead;
container != NULL;
count++, container = container->bn_flink)
{
}
return count;
}
#endif
/****************************************************************************
* Name: bluetooth_queue_frame
*
* Description:
* Add one frame to the connection's RX queue.
*
* Input Parameters:
* conn - The socket connection structure.
* framel - A single frame to add to the RX queue.
* meta - Meta data characterizing the received frane.
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned on
* any failure.
*
****************************************************************************/
static int bluetooth_queue_frame(FAR struct bluetooth_conn_s *conn,
FAR struct iob_s *frame,
FAR struct bluetooth_frame_meta_s *meta)
{
FAR struct bluetooth_container_s *container;
/* Allocate a container for the frame */
container = bluetooth_container_allocate();
if (container == NULL)
{
nerr("ERROR: Failed to allocate a container\n");
return -ENOMEM;
}
/* Initialize the container */
memset(&container->bn_raddr, 0, sizeof(bt_addr_t));
container->bn_channel = meta->bm_channel;
BLUETOOTH_ADDRCOPY(&container->bn_raddr, &meta->bm_raddr);
DEBUGASSERT(frame != NULL);
container->bn_iob = frame;
/* Add the container to the tail of the list of incoming frames */
container->bn_flink = NULL;
if (conn->bc_rxtail == NULL)
{
conn->bc_rxhead = container;
}
else
{
conn->bc_rxtail->bn_flink = container;
}
#if CONFIG_NET_BLUETOOTH_BACKLOG > 0
/* If incrementing the count would exceed the maximum bc_backlog value, then
* delete the oldest frame from the head of the RX queue.
*/
if (conn->bc_backlog >= CONFIG_NET_BLUETOOTH_BACKLOG)
{
DEBUGASSERT(conn->bc_backlog == CONFIG_NET_BLUETOOTH_BACKLOG);
/* Remove the container from the tail RX input queue. */
container = conn->bc_rxhead;
DEBUGASSERT(container != NULL);
conn->bc_rxhead = container->bn_flink;
container->bn_flink = NULL;
/* Did the RX queue become empty? */
if (conn->bc_rxhead == NULL)
{
conn->bc_rxtail = NULL;
}
DEBUGASSERT(container != NULL && container->bn_iob != NULL);
/* Free both the IOB and the container */
iob_free(container->bn_iob);
bluetooth_container_free(container);
}
else
{
/* Increment the count of frames in the queue. */
conn->bc_backlog++;
}
DEBUGASSERT((int)conn->bc_backlog == bluetooth_count_frames(conn));
#endif
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: bluetooth_input
*
* Description:
* Handle incoming Bluetooth input
*
* This function is called when the radio device driver has received an
* frame from the network. The frame from the device driver must be
* provided in by the IOB frame argument of the function call:
*
* - The frame data is in the IOB io_data[] buffer,
* - The length of the frame is in the IOB io_len field, and
* - The offset past and radio MAC header is provided in the io_offset
* field.
*
* The frame argument may refer to a single frame (a list of length one)
* or may it be the head of a list of multiple frames.
*
* - The io_flink field points to the next frame in the list (if enable)
* - The last frame in the list will have io_flink == NULL.
*
* Input Parameters:
* radio The radio network driver interface.
* framelist - The head of an incoming list of frames. Normally this
* would be a single frame. A list may be provided if
* appropriate, however.
* meta - Meta data characterizing the received frame.
*
* If there are multiple frames in the list, this metadata
* must apply to all of the frames in the list.
*
* Returned Value:
* OK The Bluetooth has been processed and can be deleted
* ERROR Hold the Bluetooth and try again later. There is a listening
* socket but no recv in place to catch the Bluetooth yet.
* Useful when a packet arrives before a recv call is in place.
*
* Assumptions:
* Called from the network diver with the network locked.
*
****************************************************************************/
int bluetooth_input(FAR struct radio_driver_s *radio,
FAR struct iob_s *framelist,
FAR struct bluetooth_frame_meta_s *meta)
{
FAR struct bluetooth_conn_s *conn;
FAR struct iob_s *frame;
FAR struct iob_s *next;
int ret = OK;
/* Check if there is a connection that will accept this packet */
conn = bluetooth_conn_active(meta);
if (conn != NULL)
{
/* Setup for the application callback (NOTE: These should not be
* used by PF_BLUETOOTH sockets).
*/
radio->r_dev.d_appdata = radio->r_dev.d_buf;
radio->r_dev.d_len = 0;
radio->r_dev.d_sndlen = 0;
/* The framelist probably contains only a single frame, but we will
* process it as a list of frames.
*/
for (frame = framelist; frame != NULL; frame = next)
{
/* Remove the frame from the list */
next = frame->io_flink;
frame->io_flink = NULL;
/* Add the frame to the RX queue */
ret = bluetooth_queue_frame(conn, frame, meta);
if (ret < 0)
{
nerr("ERROR: Failed to queue frame: %d\n", ret);
iob_free(frame);
}
}
/* Perform the application callback. The frame may be processed now
* if there is a user wait for an incoming frame. Or it may pend in
* the RX queue until some user process reads the frame. NOTE: The
* return value from bluetooth_callback would distinguish these
* cases: BLUETOOTH_NEWDATA will still be processed if the frame
* was not consumed.
*/
(void)bluetooth_callback(radio, conn, BLUETOOTH_NEWDATA);
}
else
{
nwarn("WARNING: No listener\n");
}
return ret;
}
#endif /* CONFIG_NET_BLUETOOTH */
/****************************************************************************
* net/bluetooth/bluetooth_poll.c
* Poll for the availability of ougoing Bluetooth frames
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/net/netconfig.h>
#include <nuttx/net/radiodev.h>
#include <nuttx/net/bluetooth.h>
#include "devif/devif.h"
#include "bluetooth/bluetooth.h"
#ifdef CONFIG_NET_BLUETOOTH
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: bluetooth_poll
*
* Description:
* Poll a packet "connection" structure for availability of TX data
*
* Input Parameters:
* dev - The device driver structure to use in the send operation
* conn - The packet "connection" to poll for TX data
*
* Returned Value:
* None
*
* Assumptions:
* The network is locked.
*
****************************************************************************/
void bluetooth_poll(FAR struct net_driver_s *dev,
FAR struct bluetooth_conn_s *conn)
{
FAR struct radio_driver_s *radio;
DEBUGASSERT(dev != NULL && conn != NULL);
radio = (FAR struct radio_driver_s *)dev;
/* Verify that the packet connection is valid */
if (conn != NULL)
{
/* Setup for the application callback (NOTE: These should not be
* used by PF_BLUETOOTH sockets).
*/
radio->r_dev.d_appdata = radio->r_dev.d_buf;
radio->r_dev.d_len = 0;
radio->r_dev.d_sndlen = 0;
/* Perform the application callback */
/* REVISIT: Need to pass the meta data and the IOB through the callback */
#warning Missing logic
/* Perform the application callback */
(void)bluetooth_callback(radio, conn, BLUETOOTH_POLL);
}
}
#endif /* CONFIG_NET && CONFIG_NET_PKT */
/****************************************************************************
* net/socket/bluetooth_recvfrom.c
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <assert.h>
#include <netpacket/bluetooth.h>
#include <arch/irq.h>
#include <nuttx/clock.h>
#include <nuttx/semaphore.h>
#include <nuttx/mm/iob.h>
#include <nuttx/net/net.h>
#include <nuttx/net/radiodev.h>
#include <nuttx/net/bluetooth.h>
#include <nuttx/wireless/bt_hci.h>
#include "netdev/netdev.h"
#include "devif/devif.h"
#include "socket/socket.h"
#include "bluetooth/bluetooth.h"
#ifdef CONFIG_NET_BLUETOOTH
/****************************************************************************
* Private Types
****************************************************************************/
struct bluetooth_recvfrom_s
{
FAR struct socket *ir_sock; /* Points to the parent socket structure */
FAR struct devif_callback_s *ir_cb; /* Reference to callback instance */
FAR struct sockaddr *ir_from; /* Location to return the from address */
FAR uint8_t *ir_buffer; /* Pointer to receive buffer */
size_t ir_buflen; /* Length of receive buffer */
sem_t ir_sem; /* Semaphore signals recv completion */
ssize_t ir_result; /* Success:size, failure:negated errno */
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: bluetooth_count_frames
*
* Description:
* Return the number of frames in the RX queue.
*
* Input Parameters:
* conn - The socket connection structure.
*
* Returned Value:
* The number of frames in the queue.
*
****************************************************************************/
#if defined(CONFIG_DEBUG_ASSERTIONS) && CONFIG_NET_BLUETOOTH_BACKLOG > 0
static int bluetooth_count_frames(FAR struct bluetooth_conn_s *conn)
{
FAR struct bluetooth_container_s *container;
int count;
for (count = 0, container = conn->bc_rxhead;
container != NULL;
count++, container = container->bn_flink)
{
}
return count;
}
#endif
/****************************************************************************
* Name: bluetooth_recvfrom_sender
*
* Description:
* Perform the reception operation if there are any queued frames in the
* RX frame queue.
*
* Input Parameters:
*
* Returned Value:
*
* Assumptions:
* The network is lockec
*
****************************************************************************/
static ssize_t bluetooth_recvfrom_rxqueue(FAR struct radio_driver_s *radio,
FAR struct bluetooth_recvfrom_s *pstate)
{
FAR struct bluetooth_container_s *container;
FAR struct sockaddr_bt_s *iaddr;
FAR struct bluetooth_conn_s *conn;
FAR struct iob_s *iob;
size_t copylen;
int ret = -EAGAIN;
/* Check if there is anyting in in the RX input queue */
DEBUGASSERT(pstate != NULL && pstate->ir_sock != NULL);
conn = (FAR struct bluetooth_conn_s *)pstate->ir_sock->s_conn;
DEBUGASSERT(conn != NULL);
if (conn->bc_rxhead != NULL)
{
/* Remove the container from the RX input queue. */
container = conn->bc_rxhead;
DEBUGASSERT(container != NULL);
conn->bc_rxhead = container->bn_flink;
container->bn_flink = NULL;
/* Did the RX queue become empty? */
if (conn->bc_rxhead == NULL)
{
conn->bc_rxtail = NULL;
}
#if CONFIG_NET_BLUETOOTH_BACKLOG > 0
/* Decrement the count of frames in the queue. */
DEBUGASSERT(conn->bc_backlog > 0);
conn->bc_backlog--;
DEBUGASSERT((int)conn->bc_backlog == bluetooth_count_frames(conn));
#endif
/* Extract the IOB containing the frame from the container */
iob = container->bn_iob;
container->bn_iob = NULL;
DEBUGASSERT(iob != NULL);
/* Copy the new packet data into the user buffer */
copylen = iob->io_len - iob->io_offset;
memcpy(pstate->ir_buffer, &iob->io_data[iob->io_offset], copylen);
ninfo("Received %d bytes\n", (int)copylen);
ret = copylen;
/* If a 'from' address poiner was supplied, copy the source address
* in the container there.
*/
if (pstate->ir_from != NULL)
{
iaddr = (FAR struct sockaddr_bt_s *)pstate->ir_from;
iaddr->bt_family = AF_BLUETOOTH;
BLUETOOTH_ADDRCOPY(&iaddr->bt_bdaddr, &container->bn_raddr);
iaddr->bt_channel = container->bn_channel;
}
/* Free both the IOB and the container */
iob_free(iob);
bluetooth_container_free(container);
}
return ret;
}
/****************************************************************************
* Name: bluetooth_recvfrom_eventhandler
*
* Description:
*
* Input Parameters:
*
* Returned Value:
*
* Assumptions:
* The network is locked.
*
****************************************************************************/
static uint16_t bluetooth_recvfrom_eventhandler(FAR struct net_driver_s *dev,
FAR void *pvconn,
FAR void *pvpriv,
uint16_t flags)
{
FAR struct bluetooth_recvfrom_s *pstate;
FAR struct radio_driver_s *radio;
ssize_t ret;
ninfo("flags: %04x\n", flags);
DEBUGASSERT(pvpriv != NULL && dev != NULL && pvconn != NULL);
/* Ignore polls from non Bluetooth network drivers */
if (dev->d_lltype != NET_LL_BLUETOOTH)
{
return flags;
}
/* Make sure that this is the driver to which the socket is bound. */
#warning Missing logic
pstate = (FAR struct bluetooth_recvfrom_s *)pvpriv;
radio = (FAR struct radio_driver_s *)dev;
/* 'pstate' might be null in some race conditions (?) */
if (pstate != NULL)
{
/* If a new packet is available, then complete the read action. */
if ((flags & BLUETOOTH_NEWDATA) != 0)
{
/* Attempt to receive the frame */
ret = bluetooth_recvfrom_rxqueue(radio, pstate);
if (ret > 0)
{
/* Don't allow any further call backs. */
pstate->ir_cb->flags = 0;
pstate->ir_cb->priv = NULL;
pstate->ir_cb->event = NULL;
pstate->ir_result = ret;
/* indicate that the data has been consumed */
flags &= ~BLUETOOTH_NEWDATA;
/* Wake up the waiting thread, returning the number of bytes
* actually read.
*/
nxsem_post(&pstate->ir_sem);
}
}
}
return flags;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: bluetooth_recvfrom
*
* Description:
* Implements the socket recvfrom interface for the case of the AF_INET
* and AF_INET6 address families. bluetooth_recvfrom() receives messages from
* a socket, and may be used to receive data on a socket whether or not it
* is connection-oriented.
*
* If 'from' is not NULL, and the underlying protocol provides the source
* address, this source address is filled in. The argument 'fromlen' is
* initialized to the size of the buffer associated with from, and
* modified on return to indicate the actual size of the address stored
* there.
*
* Input Parameters:
* psock A pointer to a NuttX-specific, internal socket structure
* buf Buffer to receive data
* len Length of buffer
* flags Receive flags
* from Address of source (may be NULL)
* fromlen The length of the address structure
*
* Returned Value:
* On success, returns the number of characters received. If no data is
* available to be received and the peer has performed an orderly shutdown,
* recv() will return 0. Otherwise, on errors, a negated errno value is
* returned (see recvfrom() for the list of appropriate error values).
*
* Assumptions:
* The network is locked.
*
****************************************************************************/
ssize_t bluetooth_recvfrom(FAR struct socket *psock, FAR void *buf,
size_t len, int flags, FAR struct sockaddr *from,
FAR socklen_t *fromlen)
{
FAR struct bluetooth_conn_s *conn = (FAR struct bluetooth_conn_s *)psock->s_conn;
FAR struct radio_driver_s *radio;
struct bluetooth_recvfrom_s state;
ssize_t ret;
/* If a 'from' address has been provided, verify that it is large
* enough to hold this address family.
*/
if (from != NULL && *fromlen < sizeof(struct sockaddr_bt_s))
{
return -EINVAL;
}
if (psock->s_type != SOCK_RAW)
{
nerr("ERROR: Unsupported socket type: %d\n", psock->s_type);
return -EPROTONOSUPPORT;
}
/* Perform the packet recvfrom() operation */
/* Initialize the state structure. This is done with the network
* locked because we don't want anything to happen until we are ready.
*/
net_lock();
memset(&state, 0, sizeof(struct bluetooth_recvfrom_s));
state.ir_buflen = len;
state.ir_buffer = buf;
state.ir_sock = psock;
state.ir_from = from;
/* Get the device driver that will service this transfer */
radio = bluetooth_find_device(conn, &conn->bc_laddr);
if (radio == NULL)
{
ret = -ENODEV;
goto errout_with_lock;
}
/* Before we wait for data, let's check if there are already frame(s)
* waiting in the RX queue.
*/
ret = bluetooth_recvfrom_rxqueue(radio, &state);
if (ret > 0)
{
/* Good newe! We have a frame and we are done. */
net_unlock();
return ret;
}
/* We will have to wait. This semaphore is used for signaling and,
* hence, should not have priority inheritance enabled.
*/
(void)nxsem_init(&state.ir_sem, 0, 0); /* Doesn't really fail */
(void)nxsem_setprotocol(&state.ir_sem, SEM_PRIO_NONE);
/* Set the socket state to receiving */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_RECV);
/* Set up the callback in the connection */
state.ir_cb = bluetooth_callback_alloc(&radio->r_dev, conn);
if (state.ir_cb)
{
state.ir_cb->flags = (BLUETOOTH_NEWDATA | BLUETOOTH_POLL);
state.ir_cb->priv = (FAR void *)&state;
state.ir_cb->event = bluetooth_recvfrom_eventhandler;
/* Wait for either the receive to complete or for an error/timeout to
* occur. NOTES: (1) net_lockedwait will also terminate if a signal
* is received, (2) the network is locked! It will be un-locked while
* the task sleeps and automatically re-locked when the task restarts.
*/
(void)net_lockedwait(&state.ir_sem);
/* Make sure that no further events are processed */
bluetooth_callback_free(&radio->r_dev, conn, state.ir_cb);
ret = state.ir_result;
}
else
{
ret = -EBUSY;
}
/* Set the socket state to idle */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);
nxsem_destroy(&state.ir_sem);
errout_with_lock:
net_unlock();
return ret;
}
#endif /* CONFIG_NET_BLUETOOTH */
/****************************************************************************
* net/bluetooth/bluetooth_sendto.c
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
#include <netpacket/bluetooth.h>
#include <arch/irq.h>
#include <nuttx/clock.h>
#include <nuttx/semaphore.h>
#include <nuttx/mm/iob.h>
#include <nuttx/net/radiodev.h>
#include <nuttx/net/bluetooth.h>
#include <nuttx/net/net.h>
#include <nuttx/net/ip.h>
#include <nuttx/wireless/bt_hci.h>
#include "netdev/netdev.h"
#include "devif/devif.h"
#include "socket/socket.h"
#include "bluetooth/bluetooth.h"
#ifdef CONFIG_NET_BLUETOOTH
/****************************************************************************
* Private Types
****************************************************************************/
/* This structure holds the state of the send operation until it can be
* operated upon from the interrupt level.
*/
struct bluetooth_sendto_s
{
FAR struct socket *is_sock; /* Points to the parent socket structure */
FAR struct devif_callback_s *is_cb; /* Reference to callback instance */
bt_addr_t is_destaddr; /* Frame destination address */
uint8_t is_channel; /* Frame destination channel */
sem_t is_sem; /* Used to wake up the waiting thread */
FAR const uint8_t *is_buffer; /* User buffer of data to send */
size_t is_buflen; /* Number of bytes in the is_buffer */
ssize_t is_sent; /* The number of bytes sent (or error) */
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: bluetooth_sendto_eventhandler
****************************************************************************/
static uint16_t bluetooth_sendto_eventhandler(FAR struct net_driver_s *dev,
FAR void *pvconn,
FAR void *pvpriv,
uint16_t flags)
{
FAR struct radio_driver_s *radio;
FAR struct bluetooth_sendto_s *pstate;
struct bluetooth_frame_meta_s meta;
FAR struct iob_s *iob;
int hdrlen;
int ret;
DEBUGASSERT(pvpriv != NULL && dev != NULL && pvconn != NULL);
/* Ignore polls from non Bluetooth network drivers */
if (dev->d_lltype != NET_LL_BLUETOOTH)
{
return flags;
}
/* Make sure that this is the driver to which the socket is connected. */
#warning Missing logic
pstate = (FAR struct bluetooth_sendto_s *)pvpriv;
radio = (FAR struct radio_driver_s *)dev;
ninfo("flags: %04x sent: %d\n", flags, pstate->is_sent);
if (pstate != NULL && (flags & BLUETOOTH_POLL) != 0)
{
/* Initialize the meta data */
BLUETOOTH_ADDRCOPY(&meta.bm_raddr, &pstate->is_destaddr);
meta.bm_channel = pstate->is_channel;
/* Get the Bluetooth MAC header length */
hdrlen = radio->r_get_mhrlen(radio, &meta);
if (hdrlen < 0)
{
nerr("ERROR: Failed to get header length: %d\n", hdrlen);
ret = hdrlen;
goto errout;
}
/* Verify that the user buffer can fit within the frame with this
* MAC header.
*/
DEBUGASSERT(BLUETOOTH_MAX_FRAMELEN <= CONFIG_IOB_BUFSIZE);
if (pstate->is_buflen + hdrlen > BLUETOOTH_MAX_FRAMELEN)
{
nerr("ERROR: User buffer will not fit into the frame: %u > %u\n",
(unsigned int)(pstate->is_buflen + hdrlen),
(unsigned int)CONFIG_IOB_BUFSIZE);
ret = -E2BIG;
goto errout;
}
/* Allocate an IOB to hold the frame data */
iob = iob_alloc(0);
if (iob == NULL)
{
nwarn("WARNING: Failed to allocate IOB\n");
return flags;
}
/* Initialize the IOB */
iob->io_offset = hdrlen;
iob->io_len = pstate->is_buflen + hdrlen;
iob->io_pktlen = pstate->is_buflen + hdrlen;
/* Copy the user data into the IOB */
memcpy(&iob->io_data[hdrlen], pstate->is_buffer, pstate->is_buflen);
/* And submit the IOB to the network driver */
ret = radio->r_req_data(radio, &meta, iob);
if (ret < 0)
{
nerr("ERROR: r_req_data() failed: %d\n", ret);
goto errout;
}
/* Save the successful result */
pstate->is_sent = pstate->is_buflen;
/* Don't allow any further call backs. */
pstate->is_cb->flags = 0;
pstate->is_cb->priv = NULL;
pstate->is_cb->event = NULL;
/* Wake up the waiting thread */
nxsem_post(&pstate->is_sem);
}
return flags;
errout:
/* Don't allow any further call backs. */
pstate->is_cb->flags = 0;
pstate->is_cb->priv = NULL;
pstate->is_cb->event = NULL;
pstate->is_sent = ret;
/* Wake up the waiting thread */
nxsem_post(&pstate->is_sem);
return flags;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: psock_bluetooth_sendto
*
* Description:
* If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET)
* socket, the parameters to and 'tolen' are ignored (and the error EISCONN
* may be returned when they are not NULL and 0), and the error ENOTCONN is
* returned when the socket was not actually connected.
*
* Input Parameters:
* psock A pointer to a NuttX-specific, internal socket structure
* buf Data to send
* len Length of data to send
* flags Send flags
* to Address of recipient
* tolen The length of the address structure
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* a negated errno value is retruend. See sendto() for the complete list
* of return values.
*
****************************************************************************/
ssize_t psock_bluetooth_sendto(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags,
FAR const struct sockaddr *to, socklen_t tolen)
{
FAR struct sockaddr_bt_s *destaddr;
FAR struct radio_driver_s *radio;
FAR struct bluetooth_conn_s *conn;
struct bluetooth_sendto_s state;
int ret = OK;
/* Verify that the sockfd corresponds to valid, allocated socket */
if (psock == NULL || psock->s_crefs <= 0)
{
return -EBADF;
}
conn = (FAR struct bluetooth_conn_s *)psock->s_conn;
DEBUGASSERT(conn != NULL);
/* Verify that the address is large enough to be a valid PF_BLUETOOTH
* address.
*/
if (tolen < sizeof(bt_addr_t))
{
return -EDESTADDRREQ;
}
/* Get the device driver that will service this transfer */
radio = bluetooth_find_device(conn, &conn->bc_laddr);
if (radio == NULL)
{
return -ENODEV;
}
/* Set the socket state to sending */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
/* Perform the send operation */
/* Initialize the state structure. This is done with interrupts
* disabled because we don't want anything to happen until we
* are ready.
*/
net_lock();
memset(&state, 0, sizeof(struct bluetooth_sendto_s));
/* This semaphore is used for signaling and, hence, should not have
* priority inheritance enabled.
*/
(void)nxsem_init(&state.is_sem, 0, 0); /* Doesn't really fail */
(void)nxsem_setprotocol(&state.is_sem, SEM_PRIO_NONE);
state.is_sock = psock; /* Socket descriptor to use */
state.is_buflen = len; /* Number of bytes to send */
state.is_buffer = buf; /* Buffer to send from */
/* Copy the destination address */
destaddr = (FAR struct sockaddr_bt_s *)to;
memcpy(&state.is_destaddr, &destaddr->bt_bdaddr,
sizeof(bt_addr_t));
if (len > 0)
{
/* Allocate resource to receive a callback */
state.is_cb = bluetooth_callback_alloc(&radio->r_dev, conn);
if (state.is_cb)
{
/* Set up the callback in the connection */
state.is_cb->flags = PKT_POLL;
state.is_cb->priv = (FAR void *)&state;
state.is_cb->event = bluetooth_sendto_eventhandler;
/* Notify the device driver that new TX data is available. */
netdev_txnotify_dev(&radio->r_dev);
/* Wait for the send to complete or an error to occur: NOTES: (1)
* net_lockedwait will also terminate if a signal is received, (2)
* interrupts may be disabled! They will be re-enabled while the
* task sleeps and automatically re-enabled when the task restarts.
*/
ret = net_lockedwait(&state.is_sem);
/* Make sure that no further interrupts are processed */
bluetooth_callback_free(&radio->r_dev, conn, state.is_cb);
}
}
nxsem_destroy(&state.is_sem);
net_unlock();
/* Set the socket state to idle */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);
/* Check for a errors, Errors are signaled by negative errno values
* for the send length
*/
if (state.is_sent < 0)
{
return state.is_sent;
}
/* If net_lockedwait failed, then we were probably reawakened by a signal. In
* this case, net_lockedwait will have returned negated errno appropriately.
*/
if (ret < 0)
{
return ret;
}
/* Return the number of bytes actually sent */
return state.is_sent;
}
#endif /* CONFIG_NET_BLUETOOTH */
This diff is collapsed.
......@@ -74,7 +74,8 @@
* TCP_NEWDATA IN: Set to indicate that the peer has sent us new data.
* UDP_NEWDATA OUT: Cleared (only) by the socket layer logic to indicate
* PKT_NEWDATA that the new data was consumed, suppressing further
* IEEE802154_NEWDATA attempts to process the new data.
* BLUETOOTH_NEWDATA attempts to process the new data.
* IEEE802154_NEWDATA
*
* TCP_SNDACK IN: Not used; always zero
* OUT: Set by the socket layer if the new data was consumed
......@@ -87,8 +88,8 @@
* TCP_POLL IN: Used for polling the socket layer. This is provided
* UDP_POLL periodically from the drivers to support (1) timed
* PKT_POLL operations, and (2) to check if the socket layer has
* IEEE802154_POLL data that it wants to send. These are socket oriented
* callbacks where the context depends on the specific
* BLUETOOTH_POLL data that it wants to send. These are socket oriented
* IEEE802154_POLL callbacks where the context depends on the specific
* set
* OUT: Not used
*
......@@ -177,6 +178,7 @@
#define TCP_ACKDATA (1 << 0)
#define TCP_NEWDATA (1 << 1)
#define UDP_NEWDATA TCP_NEWDATA
#define BLUETOOTH_NEWDATA TCP_NEWDATA
#define IEEE802154_NEWDATA TCP_NEWDATA
#define PKT_NEWDATA TCP_NEWDATA
#define WPAN_NEWDATA TCP_NEWDATA
......@@ -186,6 +188,7 @@
#define TCP_POLL (1 << 4)
#define UDP_POLL TCP_POLL
#define PKT_POLL TCP_POLL
#define BLUETOOTH_POLL TCP_POLL
#define IEEE802154_POLL TCP_POLL
#define WPAN_POLL TCP_POLL
#define TCP_BACKLOG (1 << 5)
......
/****************************************************************************
* net/devif/devif_poll.c
*
* Copyright (C) 2007-2010, 2012, 2014, 2016-2017 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2010, 2012, 2014, 2016-2018 Gregory Nutt. All rights
* reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
......@@ -53,6 +54,7 @@
#include "tcp/tcp.h"
#include "udp/udp.h"
#include "pkt/pkt.h"
#include "bluetooth/bluetooth.h"
#include "ieee802154/ieee802154.h"
#include "icmp/icmp.h"
#include "icmpv6/icmpv6.h"
......@@ -238,6 +240,42 @@ static int devif_poll_pkt_connections(FAR struct net_driver_s *dev,
}
#endif /* CONFIG_NET_PKT */
/****************************************************************************
* Name: devif_poll_bluetooth_connections
*
* Description:
* Poll all packet connections for available packets to send.
*
* Assumptions:
* This function is called from the MAC device driver with the network
* locked.
*
****************************************************************************/
#ifdef CONFIG_NET_BLUETOOTH
static int devif_poll_bluetooth_connections(FAR struct net_driver_s *dev,
devif_poll_callback_t callback)
{
FAR struct bluetooth_conn_s *bluetooth_conn = NULL;
int bstop = 0;
/* Traverse all of the allocated packet connections and perform the poll action */
while (!bstop && (bluetooth_conn = bluetooth_conn_next(bluetooth_conn)))
{
/* Perform the packet TX poll */
bluetooth_poll(dev, bluetooth_conn);
/* Call back into the driver */
bstop = callback(dev);
}
return bstop;
}
#endif /* CONFIG_NET_BLUETOOTH */
/****************************************************************************
* Name: devif_poll_ieee802154_connections
*
......@@ -272,7 +310,7 @@ static int devif_poll_ieee802154_connections(FAR struct net_driver_s *dev,
return bstop;
}
#endif /* CONFIG_NET_PKT */
#endif /* CONFIG_NET_IEEE802154 */
/****************************************************************************
* Name: devif_poll_icmp
......@@ -561,6 +599,15 @@ int devif_poll(FAR struct net_driver_s *dev, devif_poll_callback_t callback)
if (!bstop)
#endif
#ifdef CONFIG_NET_BLUETOOTH
{
/* Check for pending PF_BLUETOOTH socket transfer */
bstop = devif_poll_bluetooth_connections(dev, callback);
}
if (!bstop)
#endif
#ifdef CONFIG_NET_IEEE802154
{
/* Check for pending PF_IEEE802154 socket transfer */
......
......@@ -13,7 +13,7 @@ config NET_IEEE802154
---help---
Enable support for raw, IEEE 802.15.4 sockets.
Raw sockets allow receiving and transmitting IEEE 802.15.3 radio
Raw sockets allow receiving and transmitting IEEE 802.15.4 radio
frames without a layer2 protocol such as 6LoWPAN in between. Frames
received are copied into a IEEE 802.15.4 socket tap before they
enter the network. Frames written into a IEEE 802.15.4 socket will
......@@ -23,7 +23,7 @@ config NET_IEEE802154
if NET_IEEE802154
config NET_IEEE802154_FRAMELEN
int "IEEE802.15.4 Frame Length"
int "IEEE 802.15.4 Frame Length"
default 127
range 1 999999
---help---
......
......@@ -66,7 +66,7 @@
/* Frame size */
/* This maximum size of an IEEE802.15.4 frame. Certain, non-standard
/* This maximum size of an IEEE 802.15.4 frame. Certain, non-standard
* devices may exceed this value, however.
*/
......@@ -153,7 +153,6 @@ EXTERN const struct sock_intf_s g_ieee802154_sockif;
struct ieee802154_data_ind_s; /* Forward reference */
struct radio_driver_s; /* Forward reference */
struct net_driver_s; /* Forward reference */
struct eth_hdr_s; /* Forward reference */
struct socket; /* Forward reference */
struct sockaddr; /* Forward reference */
......@@ -175,7 +174,7 @@ void ieee802154_initialize(void);
* Name: ieee802154_conn_initialize
*
* Description:
* Initialize the IEEE 802.15.5 connection structure allocator. Called
* Initialize the IEEE 802.15.4 connection structure allocator. Called
* once and only from ieee802154_initialize().
*
* Assumptions:
......