BLUETOOTH(9)

NAME
BLUETOOTH - Bluetooth Device/Protocol API

SYNOPSIS
#include <netbt/bluetooth.h>
#include <netbt/hci.h>
#include <netbt/l2cap.h>
#include <netbt/rfcomm.h>
void
hci_attach(struct hci_unit *unit);
void
hci_detach(struct hci_unit *unit);
void
hci_input_event(struct hci_unit *unit, struct mbuf *m);
void
hci_input_acl(struct hci_unit *unit, struct mbuf *m);
void
hci_input_sco(struct hci_unit *unit, struct mbuf *m);
int
btproto_attach(btproto_handle *, const struct btproto *proto, void *ref);
int
btproto_bind(btproto_handle, struct sockaddr_bt *addr);
int
btproto_sockaddr(btproto_handle, struct sockaddr_bt *addr);
int
btproto_connect(btproto_handle, struct sockaddr_bt *addr);
int
btproto_peeraddr(btproto_handle, struct sockaddr_bt *addr);
int
btproto_disconnect(btproto_handle, int linger);
int
btproto_detach(btproto_handle *);
int
btproto_listen(btproto_handle);
int
btproto_send(btproto_handle, struct mbuf *mbuf);
int
btproto_rcvd(btproto_handle, size_t space);
int
btproto_setopt(btproto_handle, int optarg, void *arg);
int
btproto_getopt(btproto_handle, int optarg, void *arg);

DESCRIPTION
The Bluetooth Protocol Stack provides socket based access to Bluetooth Devices. This document describes device driver access to the stack from below, and also the general Bluetooth Protocol/Service API for layering above existing Bluetooth Protocols.

DATA TYPES
Device drivers attached to the Bluetooth Protocol Stack will make use of the struct hci_unit data type defined in <netbt/hci.h>

This contains the following data items and function callbacks which should be initialised by the device before hci_attach() is called:

    	void	 *hci_softc;		/* self reference */
    	char	 *hci_devname;		/* ->dv_xname */
    	int	  hci_ipl;		/* to block interrupts */
    	int	(*hci_enable)(struct hci_unit *);
    	void	(*hci_disable)(struct hci_unit *);
    	void	(*hci_start_cmd)(struct hci_unit *);
    	void	(*hci_start_acl)(struct hci_unit *);
    	void	(*hci_start_sco)(struct hci_unit *);

and other items of interest that will be initialised by the protocol stack:

    	uint16_t	hci_flags;
    	MBUFQ_HEAD()	hci_cmdq;
    	MBUFQ_HEAD()	hci_acltxq;
    	MBUFQ_HEAD()	hci_scotxq;
    	struct bt_stats hci_stats;

Statistics counters should be updated by the device after packets have been transmitted or received, or when errors occur.

    struct bt_stats {
    	uint32_t	err_tx;
    	uint32_t	err_rx;
    	uint32_t	cmd_tx;
    	uint32_t	evt_rx;
    	uint32_t	acl_tx;
    	uint32_t	acl_rx;
    	uint32_t	sco_tx;
    	uint32_t	sco_rx;
    	uint32_t	byte_tx;
    	uint32_t	byte_rx;
    };

Bluetooth Protocol layers attaching above the Bluetooth Protocol Stack will make use of the struct btproto data type, which is defined in <netbt/bluetooth.h> and contains the following function callbacks which should be initialised by the protocol layer before attaching to the protocol which it utilises:

    struct btproto {
    	void (*connecting)(void *);
    	void (*connected)(void *);
    	void (*disconnected)(void *, int);
    	void *(*newconn)(void *, struct sockaddr_bt *, struct sockaddr_bt *);
    	void (*complete)(void *, int);
    	void (*linkmode)(void *, int);
    	void (*input)(void *, struct mbuf *);
    };

FUNCTIONS
The following functions are related to the Bluetooth Device API.

hci_attach(unit)
    Attach Bluetooth HCI device unit to the protocol stack.

hci_detach(unit)
    Detach Bluetooth HCI device unit from the protocol stack.

hci_input_event(unit, mbuf)
    This function should be called by the device when it has an event packet to present to the protocol stack. It may be called from an interrupt routine at the hci_ipl value given above.

hci_input_acl(unit, mbuf)
    This function should be called by the device when it has an ACL data packet to present to the protocol stack. It may be called from an interrupt routine at the hci_ipl value given above.

hci_input_sco(unit, mbuf)
    This function should be called by the device when it has an SCO data packet to present to the protocol stack. It may be called from an interrupt routine at the hci_ipl value given above.

(*hci_enable)(unit)
    This will be called at the given hci_ipl level when the protocl stack wishes to enable the device. The driver should set the BTF_RUNNING flag in the unit structure.

(*hci_disable)(unit)
    This will be called at the given hci_ipl level when the protocol stack wishes to disable the device. The driver should clear the BTF_RUNNING flag in the unit structure.

(*hci_start_cmd)(unit)
    Will be called at the given hci_ipl level when command packets are available to be transmitted on the hci_cmdq queue in the hci_unit structure and the BTF_XMID_CMD flag is not set. The device should set BTF_XMIT_CMD and start sending command packets asyncrhonously until the queue is empty, then clear the BTF_XMIT_CMD flag and exit.

(*hci_start_acl)(unit)
    Will be called at the given hci_ipl level when ACL packets are available to be transmitted on the hci_acltxq queue in the hci_unit structure and the BTF_XMIT_ACL unit flag is not set. The device should set BTF_XMIT_ACL and start sending ACL packets asynchronously until the queue is empty, then clear the BTF_XMIT_ACL flag and exit.

(*hci_start_sco)(unit)
    Will be called at the given hci_ipl level when SCO packets are available to be transmitted on the hci_scotxq queue in the hci_unit structure and the BTF_XMIT_SCO flag is not set. The device should set the unit flag BTF_XMIT_SCO and start sending SCO packets asynchronously until the queue is empty, then clear the BTF_XMIT_SCO flag and exit.

The following function definitions are related to the Bluetooth Protocol API. Note that the "btproto" prefix is representative only, the protocol being utilised will have a more specific prefix with prototypes being declared in the appropriate <netbt/btproto.h> file.

btproto_attach(handle_ptr, proto, ref)
    Allocate and initialise a new protocol object at the handle_ptr address that should subsequently be passed into the other functions. proto is a pointer to the btproto structure as described above containing relevant callbacks, and ref is the argument that will be supplied to those calls.

btproto_bind(handle, addr)
    Set the local address of the protocol object described by handle to addr.

btproto_sockaddr(handle, addr)
    Copy the local address of the protocol object described by handle into addr

btproto_connect(handle, addr)
    Initiate a connection by the protocol object described by handle to the remote device described by addr. This will result in a call to either proto->connected() or proto->disconnected(), and optionally proto->connecting() with the appropriate reference as given to btproto_attach().

btproto_peeraddr(handle, addr)
    Copy the remote address of the protocol object described by handle into addr.

btproto_disconnect(handle, linger)
    Schedule a disconnection by the protocol object described by handle. This will result in a call to proto->disconnected() with the appropriate reference when the connection is torn down. If linger is zero, the disconnection will be initiated immediately and any outstanding data may be lost.

btproto_detach(handle_ptr)
    Detach the protocol object described by the value in the location of handle_ptr, and free any related memory. The pointer in the location is cleared.

btproto_listen(handle)
    Utilise the protocol object described by handle as a listening post. This will result in calls to the proto->newconn() function when incoming connections are detected.

btproto_send(handle, mbuf)
    Send data on the connection described by the protocol object.

btproto_rcvd(handle, space)
    Indicate to the protocol that space is now available in the input buffers so that flow control may be deasserted. This should also be called to indicate initial buffer space. Note that space is an absolute value.

btproto_setopt(handle, optarg, arg)
    Set options on the protocol object described by handle.

btproto_getopt(handle, optarg, arg)
    Get options for the protocol object described by handle.

(*connecting)(ref)
    This function will be called when the protocol receives information that the connection described by ref is pending.

(*connected)(ref)
    This function will be called when the connection described by ref is successful and indicates that data may now be sent.

(*disconnected)(ref, error)
    This function will be called when the connection described by ref is disconnected.

*(*newconn)(ref, laddr, raddr)
    This function will be called when the protocol receives a new incoming connection on the local device described by laddr from the remote device described by raddr. The protocol should decide if it wishes to accept the connection and should attach and return a new instance of the relevant protocol handle or NULL.

(*complete)(ref, count)
    This function will be called when the protocol has completed sending data. Complete will usually mean that the data has successfully left the device though for guaranteed protocols it can mean that the data has arrived at the other end and been acknowledged, and that count amount of data can be removed from the socket buffer. The units of the count value will be dependent on the protocol being used (eg RFCOMM is bytes, but L2CAP is packets)

(*linkmode)(ref, mode)
    This function will be called for established connections, when the link mode of the baseband link has changed. mode is the new mode.

(*input)(ref, mbuf)
    This function is called to supply new data on the connection described by ref.

CODE REFERENCES
This section describes places in the NetBSD source tree where actual code implementing or using the Bluetooth Protocol Stack can be found. All pathnames are relative to /usr/src.

The Bluetooth Protocol Stack is contained in the sys/netbt directory.

The Bluetooth Device API as described above is contained in the sys/netbt/hci_unit.c file.

For examples of the Bluetooth Protocol API see the interaction between the L2CAP upper layer in sys/netbt/l2cap_upper.c and either the L2CAP socket layer in sys/netbt/l2cap_socket.c or the bthidev(4) pseudo-device in sys/dev/bluetooth/bthidev.c.

Also, the RFCOMM upper layer in sys/netbt/rfcomm_upper.c and the RFCOMM socket layer in sys/netbt/rfcomm_socket.c.

SEE ALSO
bluetooth(4), bt3c(4), bthidev(4), ubt(4)

HISTORY
This Bluetooth Protocol Stack was written for NetBSD 4.0 by Iain Hibbert, under the sponsorship of Itronix, Inc.