What is L2CAP?
L2CAP (Logical Link Control and Adaptation Protocol) sits above the Bluetooth baseband and HCI layers. It multiplexes multiple higher-layer protocols over a single ACL link, handles segmentation and reassembly of large data packets, provides per-channel flow control, and supports quality-of-service negotiation. It can operate over BR/EDR, LE, or AMP controllers.
Key Concepts
4.2.1 Modes of Operation
The mode of operation is selected independently for each L2CAP channel. There are six defined modes:
Basic L2CAP Mode
Default mode. The header contains only minimal information: packet length and channel ID. No retransmission or flow control overhead.
Flow Control Mode
No retransmissions. Missing PDUs are detected and reported as lost. Useful when timing is more critical than reliability.
Retransmission Mode
A timer ensures all PDUs are delivered. PDUs are retransmitted if not acknowledged by the remote side within the timeout period.
Enhanced Retransmission Mode
Builds on Retransmission Mode. Adds a POLL bit to actively request a response from the remote L2CAP layer, improving reliability.
Streaming Mode
PDUs are numbered but not acknowledged. Correct ordering is maintained via sequence numbers. A flush timeout discards stale PDUs.
LE Credit-Based Flow Control
Introduced in Bluetooth 4.1. Each side provides a credit count at connection setup, indicating how many LE-frames it can accept. Credits are replenished as buffers free up.
LE Credit-Based Flow Control – How Credits Work
If credits reach zero, Device A stops sending until Device B replenishes them.
4.2.2 L2CAP PDU Types
L2CAP defines five types of Protocol Data Units (PDUs). Each type serves a specific purpose and is used in specific operational modes.
4.2.3 L2CAP Major Features
L2CAP uses a BR/EDR Controller, LE Controller, or a Dual-mode controller for transporting data. It can also use AMP controllers if available.
4.2.3.1 Protocol & Channel Multiplexing
L2CAP allows several higher-layer protocols to share the same ACL link. Each protocol is assigned a unique Channel ID (CID). The Protocol/Service Multiplexer (PSM) field identifies which higher-level protocol is connecting during L2CAP channel establishment.
CID-A
CID-B
CID-C
CID-D
BR/EDR
Controller
LE
Controller
AMP
Controller
A channel can switch between controllers (e.g. BR/EDR → AMP) for higher throughput, but can only be active on one controller at a time.
Table 4.2 – Assigned PSM Values
| Protocol | PSM Value | Description |
|---|---|---|
| SDP | 0x0001 |
Service Discovery Protocol |
| RFCOMM | 0x0003 |
RFCOMM Protocol |
| TCS-BIN | 0x0005 |
Telephony Control Specification, Binary Protocol |
| TCS-BIN-CORDLESS | 0x0007 |
Telephony Control Spec, Cordless variant |
| BNEP | 0x000F |
Bluetooth Network Encapsulation Protocol |
| HID_Control | 0x0011 |
Human Interface Device Profile |
| HID_Interrupt | 0x0013 |
Human Interface Device Profile |
| UPnP | 0x0015 |
Universal Plug and Play |
| AVCTP | 0x0017 |
Audio/Video Control Transport Protocol |
| AVDTP | 0x0019 |
Audio/Video Distribution Transport Protocol |
| UDI_C-Plane | 0x001D |
Unrestricted Digital Information Profile |
4.2.3.2 Segmentation and Reassembly (SAR)
L2CAP allows higher-layer protocols to transmit and receive packets up to 64 KB. It automatically breaks large packets into controller-sized chunks for transmission and reassembles them at the receiving end before handing data to the upper layer.
60 KB packet
Adds 4-byte header → 61,444 bytes
60 × 1021B + 1 × 180B
60 KB restored
Strips header, hands up 60 KB
Maximum ACL payload via 3-DH5 packets: 1021 bytes. L2CAP adds a 4-byte header, so 60 KB → 61,444 bytes → 61 chunks.
- Simplifies higher-layer protocols — they do not need to know the controller’s packet size limit. L2CAP negotiates a mutually suitable MTU between peers.
- Efficient retransmission — if one chunk has a transmission error, only that chunk is retransmitted, not the entire large packet.
- Interleaving — packets from different higher-layer protocols can be interleaved, preventing any single large transfer from starving other protocols.
- Buffer flexibility — controllers have limited buffer space; L2CAP lets upper layers use the host’s larger buffers and adapts packet sizes accordingly.
The MTU (Maximum Transmission Unit) is specified independently by each device — it is not negotiated as a shared value. Each device sends packets no larger than the remote device’s declared MTU. Lower MTU values mean more chunks and slower overall throughput, so the MTU setting is critical for performance-sensitive applications.
4.2.3.3 Per Channel Flow Control
HCI already provides aggregate flow control between host and controller. L2CAP extends this to per-channel granularity — each multiplexed channel can be individually throttled without affecting others.
RFCOMM data can be stopped independently while SDP and AVDTP channels continue unaffected on the same ACL link.
4.2.3.4 Error Control and Retransmissions
BlueZ – Opening an L2CAP Socket (Example)
/* BlueZ L2CAP socket example */
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
int sock;
struct sockaddr_l2 addr = { 0 };
/* Create L2CAP socket */
sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
/* Bind to local adapter */
addr.l2_family = AF_BLUETOOTH;
addr.l2_bdaddr = *BDADDR_ANY;
addr.l2_psm = htobs(0x1001); /* Custom PSM value */
bind(sock, (struct sockaddr *)&addr, sizeof(addr));
/* Connect to remote device */
memset(&addr, 0, sizeof(addr));
addr.l2_family = AF_BLUETOOTH;
str2ba("XX:XX:XX:XX:XX:XX", &addr.l2_bdaddr);
addr.l2_psm = htobs(0x1001);
connect(sock, (struct sockaddr *)&addr, sizeof(addr));
Continue Learning Bluetooth
Explore SDP, RFCOMM, AVDTP and other Bluetooth upper-layer profiles to build on your L2CAP foundation.
