NG_L2CAP(4)
π NAME π β NG_L2CAP(4) in the Kernel Interfaces Manual
Ok bestie, meet ng_l2cap π It's a Netgraph node type that implements Bluetooth Logical Link Control and Adaptation Protocol (L2CAP). That's the whole vibe: Netgraph node, Bluetooth L2CAP, no cap.
β¨ SYNOPSIS β¨
#include <sys/types.h>
#include <netgraph/bluetooth/include/ng_hci.h>
#include <netgraph/bluetooth/include/ng_l2cap.h>
π DESCRIPTION π
The l2cap node type is a Netgraph node type that implements Bluetooth Logical Link Control and Adaptation Protocol as per chapter D of the Bluetooth Specification Book v1.1. Periodt.
L2CAP provides connection-oriented and connectionless data services to upper layer protocols with protocol multiplexing capability, segmentation and reassembly operation, and group abstractions. L2CAP permits higher level protocols and applications to transmit and receive L2CAP data packets up to 64 kilobytes in length. Iconic behavior, honestly.
π§ L2CAP Assumptions π§
- The ACL link between two units is set up. The Baseband provides orderly delivery of data packets, although there might be individual packet corruption and duplicates. No more than one ACL link exists between any two devices.
- The Baseband always provides the impression of full-duplex communication channels. This does not imply that all L2CAP communications are bi-directional. Multicasts and unidirectional traffic (e.g., video) do not require duplex channels.
- L2CAP provides a reliable channel using the mechanisms available at the Baseband layer. The Baseband always performs data integrity checks when requested and resends data until it has been successfully acknowledged or a timeout occurs. As acknowledgements may be lost, timeouts may occur even after the data has been successfully sent.
π L2CAP GENERAL OPERATION π
The Logical Link Control and Adaptation Protocol (L2CAP) is based around the concept of βchannelsβ. Each channel is bound to a single protocol in a many-to-one fashion. Multiple channels can be bound to the same protocol, but a channel cannot be bound to multiple protocols. Each L2CAP packet received on a channel is directed to the appropriate higher level protocol.
Each one of the end-points of an L2CAP channel is referred to by a channel identifier. Channel identifiers (CIDs) are local names representing a logical channel end-point on the device. Identifiers from 0x0001 to 0x003F are reserved for specific L2CAP functions. The null identifier (0x0000) is defined as an illegal identifier and must never be used as a destination end-point. All L2CAP signalling commands are sent to CID 0x0001. CID 0x0002 is reserved for group-oriented channel. The same CID must not be reused as a local L2CAP channel endpoint for multiple simultaneous L2CAP channels between a local device and some remote device.
CID assignment is relative to a particular device and a device can assign CIDs independently from other devices. Thus, even if the same CID value has been assigned to (remote) channel endpoints by several remote devices connected to a single local device, the local device can still uniquely associate each remote CID with a different device.
π Channel Operational States π
NG_L2CAP_CLOSEDβ In this state, there is no channel associated with this CID. This is the only state when a link level connection (Baseband) may not exist. Link disconnection forces all other states into theNG_L2CAP_CLOSEDstate.NG_L2CAP_W4_L2CAP_CON_RSPβ In this state, the CID represents a local end-point and an L2CAP Connect Request message has been sent referencing this endpoint and it is now waiting for the corresponding L2CAP Connect Response message.NG_L2CAP_W4_L2CA_CON_RSPβ In this state, the remote end-point exists and an L2CAP Connect Request has been received by the local L2CAP entity. An L2CA Connect Indication has been sent to the upper layer and the part of the local L2CAP entity processing the received L2CAP Connect Request waits for the corresponding response. The response may require a security check to be performed.NG_L2CAP_CONFIGβ In this state, the connection has been established but both sides are still negotiating the channel parameters. The Configuration state may also be entered when the channel parameters are being renegotiated. Prior to entering theNG_L2CAP_CONFIGstate, all outgoing data traffic is suspended since the traffic parameters of the data traffic are to be renegotiated. Incoming data traffic is accepted until the remote channel endpoint has entered theNG_L2CAP_CONFIGstate. In theNG_L2CAP_CONFIGstate, both sides will issue L2CAP Configuration Request messages if only defaults are being used, a null message will be sent. If a large amount of parameters need to be negotiated, multiple messages will be sent to avoid any MTU limitations and negotiate incrementally. Moving from theNG_L2CAP_CONFIGstate to theNG_L2CAP_OPENstate requires both sides to be ready. An L2CAP entity is ready when it has received a positive response to its final request and it has positively responded to the final request from the remote device.NG_L2CAP_OPENβ In this state, the connection has been established and configured, and data flow may proceed.NG_L2CAP_W4_L2CAP_DISCON_RSPβ In this state, the connection is shutting down and an L2CAP Disconnect Request message has been sent. This state is now waiting for the corresponding response.NG_L2CAP_W4_L2CA_DISCON_RSPβ In this state, the connection on the remote endpoint is shutting down and an L2CAP Disconnect Request message has been received. An L2CA Disconnect Indication has been sent to the upper layer to notify the owner of the CID that the remote endpoint is being closed. This state is now waiting for the corresponding response from the upper layer before responding to the remote endpoint.
π¦ Protocol Multiplexing π¦
L2CAP supports protocol multiplexing because the Baseband Protocol does not support any βtypeβ field identifying the higher layer protocol being multiplexed above it. L2CAP is able to distinguish between upper layer protocols such as the Service Discovery Protocol, RFCOMM and Telephony Control.
π Segmentation and Reassembly π
The data packets defined by the Baseband Protocol are limited in size. Large L2CAP packets must be segmented into multiple smaller Baseband packets prior to their transmission over the air. Similarly, multiple received Baseband packets may be reassembled into a single larger L2CAP packet.
π Quality of Service π
The L2CAP connection establishment process allows the exchange of information regarding the quality of service (QoS) expected between two Bluetooth units.
πΈ Groups πΈ
The Baseband Protocol supports the concept of a piconet, a group of devices synchronously hopping together using the same clock. The L2CAP group abstraction permits implementations to efficiently map protocol groups on to piconets.
The following features are outside the scope of L2CAP responsibilities:
- L2CAP does not transport audio designated for SCO links.
- L2CAP does not enforce a reliable channel or ensure data integrity, that is, L2CAP performs no retransmissions or checksum calculations.
- L2CAP does not support a reliable multicast channel.
- L2CAP does not support the concept of a global group name.
π HOOKS π
This node type supports the following hooks:
hciβ Bluetooth Host Controller Interface downstream hook.l2cβ Upper layer protocol upstream hook. Usually the Bluetooth L2CAP socket layer is connected to the hook.ctlβ Control hook. Usually the Bluetooth raw L2CAP sockets layer is connected to the hook.
πΈ INTERFACE TO THE UPPER LAYER PROTOCOLS (L2CA CONTROL MESSAGES) πΈ
okay so bestie, the Bluetooth specification says L2CA requests have to block until the response is ready. no skipping the line, no cutting corners. π
so the L2CAP node uses the token field from the Netgraph message header to match up L2CA requests with their responses. that means the upper layer protocol must populate token β it's not optional, it's the whole system. π
then the L2CAP node queues the request and starts working on it. later, when the response is ready (or when a timeout has occurred), the L2CAP node creates a new Netgraph message, sets the token and the NFG_RESP flag, and sends it on up to the upper layer. β¨
heads up though: L2CA indication messages will not populate token and will not set the NGF_RESP flag. the original literally says "There is no reason for this, because they are just notifications and do not require acknowledgment." like okay king, we respect the honesty ππ
π¨ the L2CA messages, one by one π¨
NGM_L2CAP_L2CA_CONβ asks for a channel to be created, i.e. a logical connection to a physical address. input params: the target protocol (PSM) and the remote device's 48-bit address (BD_ADDR). output params: the local CID (LCID) that the local L2CAP entity hands out, plus theResultof the request. and ifResultis showing a pending notification? thenStatusmight have more tea on what's holding up the connection. π«NGM_L2CAP_L2CA_CON_INDβ this one carries the params for: the address of the remote device that sent the connection request, the local CID for the channel being requested, theIdentifierfrom inside the request, and thePSMvalue the request is aiming at.NGM_L2CAP_L2CA_CON_RSPβ this is you responding to a connection request event indication. input params: remote device's 48-bit address, theIdentifiersent in the request, local CID, theResponsecode, and theStatusattached to that Response code. output param: theResultof the service request. > β οΈ and you must call this no more than once after receiving the indication. once. that's it. π«NGM_L2CAP_L2CA_CFGβ requests the initial configuration (or a reconfiguration, glow-up edition β¨) of a channel to a new set of channel parameters. input params: local CID endpoint, new incoming receivable MTU (InMTU), new outgoing flow spec-ification, and flush and link timeouts. output params:Result, accepted incoming MTU (InMTU), the remote side's flow requests, and flush and link timeouts.NGM_L2CAP_L2CA_CFG_INDβ this message has the params indicating the local CID of the channel the request was sent to, the outgoing MTU size (that's the max packet that can be sent across the channel), and the flowspec describing the characteristics of the incoming data. and bestie, note this: all other channel parameters are set to their default values if they weren't provided by the remote device. defaults it is. π€·βοΈNGM_L2CAP_L2CA_CFG_RSPβ you're responding to a configuration request event indication. input params include the local CID of the endpoint being configured, the outgoing transmit MTU (which may be equal to or less than theOutMTUparameter in the configuration indication event), and the accepted flowspec for incoming traffic. output param: theResultvalue.NGM_L2CAP_L2CA_QOS_INDβ this message includes the param indicating the address of the remote Bluetooth device where the QoS contract has been violated. someone broke the rules and we're being told about it. πNGM_L2CAP_L2CA_DISCONβ requests disconnection of the channel. input param: theCIDrepresenting the local channel endpoint. output param:Result.Resultis zero if an L2CAP Disconnect Response is received, otherwise a non-zero value comes back. > β οΈ and once disconnection has been requested, no process will be able to successfully read or write from the CID. that channel is gone gone. πNGM_L2CAP_L2CA_DISCON_INDβ this message includes the param indicating the localCIDthe request has been sent to.NGM_L2CAP_L2CA_WRITEβ response to a transfer-of-data request. the actual data must be received from the appropriate upstream hook, and it must be prepended with a header defined like this:
/* L2CA data packet header */
typedef struct {
uint32_t token; /* token to use in L2CAP_L2CA_WRITE */
uint16_t length; /* length of the data */
uint16_t lcid; /* local channel ID */
} __attribute__ ((packed)) ng_l2cap_l2ca_hdr_t;
the output parameters are Result and Length of data written. π
NGM_L2CAP_L2CA_GRP_CREATEβ requests the creation of aCIDto represent a logical connection to multiple devices. input param: thePSMvalue that the outgoing connectionless traffic is labelled with, plus the filter used for incoming traffic. output param: theCIDrepresenting the local endpoint. on creation the group is empty, but incoming traffic destined for thePSMvalue is readable. > π§ heads up: this request has not been implemented.NGM_L2CAP_L2CA_GRP_CLOSEβ using this message closes down a Group. > π§ this request has not been implemented.NGM_L2CAP_L2CA_GRP_ADD_MEMBERβ requests adding a member to a group. input param includes theCIDrepresenting the group and theBD_ADDRof the group member to be added. output paramResultconfirms success or failure of the request. > π§ this request has not been implemented.NGM_L2CAP_L2CA_GRP_REM_MEMBERβ requests removing a member from a group. input params include theCIDrepresenting the group and theBD_ADDRof the group member to be removed. output paramResultconfirms success or failure of the request. > π§ this request has not been implemented.NGM_L2CAP_L2CA_GRP_MEMBERSHIPβ requests a report of the members of a group. input paramCIDrepresents the group being queried. output paramResultconfirms success or failure of the operation. and if theResultis successful,BD_ADDR_Lstis a list of the Bluetooth addresses of theNmembers of the group. > π§ this request has not been implemented.NGM_L2CAP_L2CA_PINGβ kicks off an L2CA Echo Request message and the reception of the corresponding L2CAP Echo Response message. input params: remote Bluetooth deviceBD_ADDR,Echo Data, andLengthof the echo data. output params:Result,Echo Data, andLengthof the echo data. πNGM_L2CAP_L2CA_GET_INFOβ kicks off an L2CA Information Request message and the reception of the corresponding L2CAP Info Response message. input params: remote Bluetooth deviceBD_ADDRandInformation Type. output params:Result,Information Data, andSizeof the information data. πNGM_L2CAP_L2CA_ENABLE_CLTβ request to disable (or enable) the reception of connectionless packets. input param: thePSMvalue indicating the service that should be blocked (or unblocked), plus theEnableflag.
ποΈ NETGRAPH CONTROL MESSAGES ποΈ
this node type supports the generic control messages, plus these ones:
NGM_L2CAP_NODE_GET_FLAGSβ returns the current state for the node.NGM_L2CAP_NODE_GET_DEBUGβ returns an integer holding the current debug level for the node.NGM_L2CAP_NODE_SET_DEBUGβ takes an integer argument and sets the current debug level for the node. πNGM_L2CAP_NODE_GET_CON_LISTβ returns a list of active baseband connections (i.e., ACL links).NGM_L2CAP_NODE_GET_CHAN_LISTβ returns a list of active L2CAP channels.NGM_L2CAP_NODE_GET_AUTO_DISCON_TIMOβ returns an integer holding the current value of the auto disconnect timeout, in sec.NGM_L2CAP_NODE_SET_AUTO_DISCON_TIMOβ accepts an integer and sets the value of the auto disconnect timeout, in sec. > β¨ fun fact: the special value of0(zero) disables the auto disconnect timeout entirely.
π SHUTDOWN π
this node shuts down when it receives an NGM_SHUTDOWN control message, or when all hooks have been disconnected. bye bestie, it was real. π¦
π SEE ALSO π
netgraph(4), l2control(8), l2ping(8), ngctl(8)
π HISTORY π
the l2cap node type was implemented in FreeBSD 5.0. vintage but make it iconic. π
π AUTHORS π
Maksim Yevmenkin <m_evmenkin@yahoo.com> β thank you for your service, legend. π«Ά
π BUGS π
"Most likely. Please report if found."
that's it. that's the whole bug section. the manpage is so real for that π not me feeling personally seen by a FreeBSD manpage.
okay bestie that's a wrap!! this page is from the Debian manual, dated July 4, 2002 β yeah, it's old, but it still ate, fr fr. go forth and connect some Bluetooth devices. π β¨πΈπ¦π
π¦ where this page comes from
- debian bookworm: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- debian trixie: freebsd-manpages 12.2-2 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu jammy: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu noble: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu questing: freebsd-manpages 12.2-2
- ubuntu resolute: freebsd-manpages 12.2-2build1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu stonking: freebsd-manpages 12.2-2build1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms