BLUETOOTH(9)
β¨ NAME β¨
This is the BLUETOOTH(9) man page, and it's literally the glow-up guide for talking to Bluetooth devices from the kernel. The official vibe? Bluetooth Device/Protocol API. No cap. π
π¦ SYNOPSIS π¦
Here's the include vibe, bestie:
#include <netbt/bluetooth.h>
#include <netbt/hci.h>
#include <netbt/l2cap.h>
#include <netbt/rfcomm.h>
Then the function prototypes, all iconic:
struct hci_unit *
hci_attach(const struct hci_if *hci_if, device_t dev, uint16_t flags);
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 gives you socket-based access to Bluetooth devices β like, it's the whole vibe check for making Bluetooth stuff work. This doc? It's for device driver access to the stack from below (yes, from below bestie, we're going deep) and also the general Bluetooth Protocol/Service API for layering stuff above existing Bluetooth Protocols. It's giving full-stack energy. π₯
π DATA TYPES π
So if you're a device driver attaching to the Bluetooth Protocol Stack, you gotta pass a pointer to a struct hci_if β that's defined in <netbt/hci.h> and it holds the driver info, like this:
struct hci_if {
int (*enable)(device_t);
void (*disable)(device_t);
void (*output_cmd)(device_t, struct mbuf *);
void (*output_acl)(device_t, struct mbuf *);
void (*output_sco)(device_t, struct mbuf *);
void (*get_stats)(device_t, struct bt_stats *, int);
int ipl;
};
Real talk: statistics counters should be updated by the device after packets have been transmitted or received, or when errors occur. Don't skip that, bestie. π
And here's the stats struct, struct bt_stats:
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;
};
Now, Bluetooth Protocol layers that attach above the Bluetooth Protocol Stack? They use the struct btproto data type β defined in <netbt/bluetooth.h> β and it's packed with function callbacks that the protocol layer should initialize before attaching to the protocol it uses. Like, set these up first, okay? π
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 π οΈ
π Bluetooth Device API Functions π
These are the functions related to the Bluetooth Device API. Let's go. π
hci_attach(hci_if, dev)β Attach Bluetooth HCI device dev to the protocol stack in the manner described by hci_if. Driver quirks? You can register them by passing the correspondingBTF_xxxxflag in the flags argument.hci_attach()will return astruct hci_unithandle β keep that, you'll pass it to the protocol stack in other calls. It's giving main character handle energy. π«Άhci_detach(unit)β Detach Bluetooth HCI unit from the device. Bye bestie π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 ipl value given in thehci_ifdescriptor. So yes, interrupt vibes are allowed. β‘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 ipl value given in thehci_ifdescriptor. Same energy, different packet. π¦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 ipl value given in thehci_ifdescriptor. SCO packets also get the interrupt glow-up. β¨(*enable)(dev)β This will be called when the protocol stack wishes to enable the device. Turn it on, bestie. π(*disable)(dev)β This will be called when the protocol stack wishes to disable the device. Turn it off, periodt. π΄(*output_cmd)(dev, mbuf)β Will be called to output command packets on the device. The device is responsible for arbitrating access to the output queue, and output commands should be sent asynchronously. The device owns the mbuf and should release it when sent. Don't forget to free it, fr fr. ποΈ(*output_acl)(dev, mbuf)β Will be called to output ACL data packets on the device. The device is responsible for arbitrating access to the output queue, and ACL data packets should be sent asynchronously. The device owns the mbuf and should release it when sent. Same rule: you own it, you release it. π―(*output_sco)(dev, mbuf)β Will be called to output SCO data packets on the device. The device is responsible for arbitrating access to the output queue, and SCO data packets should be sent asynchronously. When the SCO data packet has been placed on the device and the mbuf is no longer required, it should be returned to the Bluetooth protocol stack via thehci_complete_sco()call. So special rule for SCO, iykyk. π§(*get_stats)(dev, dest, flush)β Will be called when IO statistics are requested. Thebt_statsstructure dest should be filled in, and if the flush argument is true, statistics should be reset. So fill it up and maybe flush it, depending. π
π Bluetooth Protocol API Functions π
Now these function definitions are related to the Bluetooth Protocol API. Quick note bestie: the "btproto" prefix is representative only β the protocol being used will have a more specific prefix with prototypes being declared in the appropriate <netbt/btproto.h> file. So don't come for me if it's not literally btproto in your code. π
btproto_attach(handle_ptr, proto, ref)β Allocate and initialize a new protocol object at the handle_ptr address that should subsequently be passed into the other functions. proto is a pointer to thebtprotostructure as described above containing relevant callbacks, and ref is the argument that will be supplied to those calls. It's like setting up your little protocol baby. πΌbtproto_bind(handle, addr)β Set the local address of the protocol object described by handle to addr. Local address = set. πbtproto_sockaddr(handle, addr)β Copy the local address of the protocol object described by handle into addr. Copy-paste but make it kernel. π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 eitherproto->connected()orproto->disconnected(), and optionallyproto->connecting()with the appropriate reference as given tobtproto_attach(). So you'll get a callback, bestie. π€btproto_peeraddr(handle, addr)β Copy the remote address of the protocol object described by handle into addr. Remote address = copied. πbtproto_disconnect(handle, linger)β Schedule a disconnection by the protocol object described by handle. This will result in a call toproto->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. β οΈ So like, zero linger means bye-bye data. Be careful.
β οΈ Warning bestie: if linger is zero, disconnection is immediate and outstanding data may be lost. That's not a drill. π
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. Clean up, clean up. π§Ήbtproto_listen(handle)β Use the protocol object described by handle as a listening post. This will result in calls to theproto->newconn()function when incoming connections are detected. It's giving waiting-for-the-call energy. βοΈbtproto_send(handle, mbuf)β Send data on the connection described by the protocol object. Slide into their DMs with data. π€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. So not a delta, bestie, an absolute value. πbtproto_setopt(handle, optarg, arg)β Set options on the protocol object described by handle. Options = set. ποΈbtproto_getopt(handle, optarg, arg)β Get options for the protocol object described by handle. Options = got. ποΈ
π¦ Protocol Callbacks π¦
These are the callbacks you initialize in struct btproto:
(*connecting)(ref)β This function will be called when the protocol receives information that the connection described by ref is pending. Pending = not yet connected, just vibing. β³(*connected)(ref)β This function will be called when the connection described by ref is successful and indicates that data may now be sent. Success! Send data now. π(*disconnected)(ref, error)β This function will be called when the connection described by ref is disconnected. It's over, bestie. π*(*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 orNULL. So you can accept or reject, your call. π(*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 (e.g. RFCOMM is bytes, but L2CAP is packets). So count your units correctly, iykyk. π¦(*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. Link mode glow-up. π(*input)(ref, mbuf)β This function is called to supply new data on the connection described by ref. New data incoming! π₯
β¨ CODE REFERENCES β¨
okay so if you wanna go read the actual source (and honestly? mood π ), here's where everything lives:
- the whole Bluetooth Protocol Stack is chillin' in the
sys/netbtdirectory π«Ά - the Bluetooth Device API (all the stuff described above, bestie) is hanging out in
sys/netbt/hci_unit.c - for examples of the Bluetooth Protocol API, go peek at how the L2CAP upper layer in
sys/netbt/l2cap_upper.ctalks to either the L2CAP socket layer insys/netbt/l2cap_socket.cor thebthidev(4)pseudo-device insys/dev/bluetooth/bthidev.cπ - also!!! the RFCOMM upper layer in
sys/netbt/rfcomm_upper.cand the RFCOMM socket layer insys/netbt/rfcomm_socket.cβ same vibes, different layer π¦
like, the way this codebase is organised is genuinely giving "someone actually cared" and we love that for us πΈ
π SEE ALSO π
go touch grass in these other pages, iykyk:
π HISTORY π
okay so lore time π«Ά this Bluetooth Protocol Stack was written for NetBSD 4.0 by Iain Hibbert, under the sponsorship of Itronix, Inc. β iconic behaviour, no cap π
and that's a wrap on BLUETOOTH(9), bestie π go forth and stack those protocols, you absolute main character π¦β¨
this page came from the Debian crew, dated November 20, 2007 β oldie but a goodie, lowkey historic π
π¦ where this page comes from
- nixpkgs unstable: netbsd-source 11.0
- Copyright (c) 2006 Itronix Inc
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms