* Copyright 2024, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _L2CAP_H_
#define _L2CAP_H_
#include <bluetooth/bluetooth.h>
* can have open simultaneously is (L2CAP_LAST_CID - L2CAP_FIRST_CID) = 65471.
* (This does not depend on the number of connections.) */
#define L2CAP_NULL_CID 0x0000
#define L2CAP_SIGNALING_CID 0x0001
#define L2CAP_CONNECTIONLESS_CID 0x0002
#define L2CAP_FIRST_CID 0x0040
#define L2CAP_LAST_CID 0xffff
* L2CAP_SIGNALING_CID. Thus only (L2CAP_LAST_IDENT - L2CAP_FIRST_IDENT),
* i.e. 254, commands can be pending simultaneously for a connection. */
#define L2CAP_NULL_IDENT 0x00
#define L2CAP_FIRST_IDENT 0x01
#define L2CAP_LAST_IDENT 0xff
#define L2CAP_MTU_MINIMUM 48
#define L2CAP_MTU_DEFAULT 672
#define L2CAP_MTU_MAXIMUM 0xffff
#define L2CAP_FLUSH_TIMEOUT_DEFAULT 0xffff /* always retransmit */
#define L2CAP_LINK_TIMEOUT_DEFAULT 0xffff
#define L2CAP_PSM_ANY 0x0000 /* Any/Invalid PSM */
#define L2CAP_PSM_SDP 0x0001 /* Service Discovery Protocol */
#define L2CAP_PSM_RFCOMM 0x0003 /* RFCOMM protocol */
#define L2CAP_PSM_TCS_BIN 0x0005 /* Telephony Control Protocol */
#define L2CAP_PSM_TCS_BIN_CORDLESS 0x0007 /* TCS cordless */
#define L2CAP_PSM_BNEP 0x000F /* BNEP */
#define L2CAP_PSM_HID_CTRL 0x0011 /* HID control */
#define L2CAP_PSM_HID_INT 0x0013 /* HID interrupt */
#define L2CAP_PSM_UPnP 0x0015 /* UPnP (ESDP) */
#define L2CAP_PSM_AVCTP 0x0017 /* AVCTP */
#define L2CAP_PSM_AVDTP 0x0019 /* AVDTP */
typedef struct {
uint16 length;
uint16 dcid;
} _PACKED l2cap_basic_header;
typedef struct {
uint16 psm;
} _PACKED l2cap_connectionless_header;
#define L2CAP_CONNECTIONLESS_MTU_MAXIMUM (L2CAP_MTU_MAXIMUM - sizeof(l2cap_connectionless_header))
typedef struct {
uint8 code;
#define L2CAP_IS_SIGNAL_REQ(code) (((code) & 1) == 0)
#define L2CAP_IS_SIGNAL_RSP(code) (((code) & 1) == 1)
uint8 ident;
uint16 length;
} _PACKED l2cap_command_header;
#define L2CAP_COMMAND_REJECT_RSP 0x01
typedef struct {
enum : uint16 {
REJECTED_NOT_UNDERSTOOD = 0x0000,
REJECTED_MTU_EXCEEDED = 0x0001,
REJECTED_INVALID_CID = 0x0002,
}; uint16 reason;
} _PACKED l2cap_command_reject;
typedef union {
struct {
uint16 mtu;
} _PACKED mtu_exceeded;
struct {
uint16 scid;
uint16 dcid;
} _PACKED invalid_cid;
} l2cap_command_reject_data;
#define L2CAP_CONNECTION_REQ 0x02
typedef struct {
uint16 psm;
uint16 scid;
} _PACKED l2cap_connection_req;
#define L2CAP_CONNECTION_RSP 0x03
typedef struct {
uint16 dcid;
uint16 scid;
enum : uint16 {
RESULT_SUCCESS = 0x0000,
RESULT_PENDING = 0x0001,
RESULT_PSM_NOT_SUPPORTED = 0x0002,
RESULT_SECURITY_BLOCK = 0x0003,
RESULT_NO_RESOURCES = 0x0004,
RESULT_INVALID_SCID = 0x0005,
RESULT_SCID_ALREADY_ALLOCATED = 0x0006,
}; uint16 result;
enum : uint16 {
NO_STATUS_INFO = 0x0000,
STATUS_AUTHENTICATION_PENDING = 0x0001,
STATUS_AUTHORIZATION_PENDING = 0x0002,
}; uint16 status;
} _PACKED l2cap_connection_rsp;
#define L2CAP_CONFIGURATION_REQ 0x04
typedef struct {
uint16 dcid;
uint16 flags;
} _PACKED l2cap_configuration_req;
#define L2CAP_CONFIGURATION_RSP 0x05
typedef struct {
uint16 scid;
uint16 flags;
#define L2CAP_CFG_FLAG_CONTINUATION 0x0001
enum : uint16 {
RESULT_SUCCESS = 0x0000,
RESULT_UNACCEPTABLE_PARAMS = 0x0001,
RESULT_REJECTED = 0x0002,
RESULT_UNKNOWN_OPTION = 0x0003,
RESULT_PENDING = 0x0004,
RESULT_FLOW_SPEC_REJECTED = 0x0005,
}; uint16 result;
} _PACKED l2cap_configuration_rsp;
typedef struct {
enum : uint8 {
OPTION_MTU = 0x01,
OPTION_FLUSH_TIMEOUT = 0x02,
OPTION_QOS = 0x03,
OPTION_HINT_BIT = 0x80,
}; uint8 type;
uint8 length;
} _PACKED l2cap_configuration_option;
typedef struct {
uint8 flags;
uint8 service_type;
uint32 token_rate;
uint32 token_bucket_size;
uint32 peak_bandwidth;
uint32 access_latency;
uint32 delay_variation;
} _PACKED l2cap_qos;
typedef union {
uint16 mtu;
uint16 flush_timeout;
l2cap_qos qos;
} l2cap_configuration_option_value;
#define L2CAP_DISCONNECTION_REQ 0x06
typedef struct {
uint16 dcid;
uint16 scid;
} _PACKED l2cap_disconnection_req;
#define L2CAP_DISCONNECTION_RSP 0x07
typedef l2cap_disconnection_req l2cap_disconnection_rsp;
#define L2CAP_ECHO_REQ 0x08
#define L2CAP_ECHO_RSP 0x09
#define L2CAP_MAX_ECHO_SIZE \
(L2CAP_MTU_MAXIMUM - sizeof(l2cap_command_header))
#define L2CAP_INFORMATION_REQ 0x0a
typedef struct {
enum : uint16 {
TYPE_CONNECTIONLESS_MTU = 0x0001,
TYPE_EXTENDED_FEATURES = 0x0002,
TYPE_FIXED_CHANNELS = 0x0003,
}; uint16 type;
} _PACKED l2cap_information_req;
#define L2CAP_INFORMATION_RSP 0x0b
typedef struct {
uint16 type;
enum : uint16 {
RESULT_SUCCESS = 0x0000,
RESULT_NOT_SUPPORTED = 0x0001,
}; uint16 result;
} _PACKED l2cap_information_rsp;
typedef union {
uint16 mtu;
uint32 extended_features;
} _PACKED l2cap_information_rsp_data;
#endif