1 /* 2 * Copyright 2024, Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _L2CAP_H_ 6 #define _L2CAP_H_ 7 8 #include <bluetooth/bluetooth.h> 9 10 11 /* Channel IDs */ 12 /*! These are unique for a unit. Thus the total number of channels that a unit 13 * can have open simultaneously is (L2CAP_LAST_CID - L2CAP_FIRST_CID) = 65471. 14 * (This does not depend on the number of connections.) */ 15 #define L2CAP_NULL_CID 0x0000 16 #define L2CAP_SIGNALING_CID 0x0001 17 #define L2CAP_CONNECTIONLESS_CID 0x0002 18 /* 0x0003-0x003f: reserved */ 19 #define L2CAP_FIRST_CID 0x0040 20 #define L2CAP_LAST_CID 0xffff 21 22 23 /* Idents */ 24 /*! Command idents are unique within a connection, since there is only one 25 * L2CAP_SIGNALING_CID. Thus only (L2CAP_LAST_IDENT - L2CAP_FIRST_IDENT), 26 * i.e. 254, commands can be pending simultaneously for a connection. */ 27 #define L2CAP_NULL_IDENT 0x00 28 #define L2CAP_FIRST_IDENT 0x01 29 #define L2CAP_LAST_IDENT 0xff 30 31 32 /* MTU */ 33 #define L2CAP_MTU_MINIMUM 48 34 #define L2CAP_MTU_DEFAULT 672 35 #define L2CAP_MTU_MAXIMUM 0xffff 36 37 38 /* Timeouts */ 39 #define L2CAP_FLUSH_TIMEOUT_DEFAULT 0xffff /* always retransmit */ 40 #define L2CAP_LINK_TIMEOUT_DEFAULT 0xffff 41 42 43 /* Protocol/Service Multiplexer (PSM) values */ 44 #define L2CAP_PSM_ANY 0x0000 /* Any/Invalid PSM */ 45 #define L2CAP_PSM_SDP 0x0001 /* Service Discovery Protocol */ 46 #define L2CAP_PSM_RFCOMM 0x0003 /* RFCOMM protocol */ 47 #define L2CAP_PSM_TCS_BIN 0x0005 /* Telephony Control Protocol */ 48 #define L2CAP_PSM_TCS_BIN_CORDLESS 0x0007 /* TCS cordless */ 49 #define L2CAP_PSM_BNEP 0x000F /* BNEP */ 50 #define L2CAP_PSM_HID_CTRL 0x0011 /* HID control */ 51 #define L2CAP_PSM_HID_INT 0x0013 /* HID interrupt */ 52 #define L2CAP_PSM_UPnP 0x0015 /* UPnP (ESDP) */ 53 #define L2CAP_PSM_AVCTP 0x0017 /* AVCTP */ 54 #define L2CAP_PSM_AVDTP 0x0019 /* AVDTP */ 55 /* < 0x1000: reserved */ 56 /* >= 0x1000: dynamically assigned */ 57 58 59 typedef struct { 60 uint16 length; /* payload size */ 61 uint16 dcid; /* destination channel ID */ 62 } _PACKED l2cap_basic_header; 63 64 65 /* Connectionless traffic ("CLT") */ 66 typedef struct { 67 /* dcid == L2CAP_CONNECTIONLESS_CID (0x2) */ 68 uint16 psm; 69 } _PACKED l2cap_connectionless_header; 70 #define L2CAP_CONNECTIONLESS_MTU_MAXIMUM (L2CAP_MTU_MAXIMUM - sizeof(l2cap_connectionless_header)) 71 72 73 typedef struct { 74 uint8 code; /* command opcode */ 75 #define L2CAP_IS_SIGNAL_REQ(code) (((code) & 1) == 0) 76 #define L2CAP_IS_SIGNAL_RSP(code) (((code) & 1) == 1) 77 uint8 ident; /* identifier to match request and response */ 78 uint16 length; /* command parameters length */ 79 } _PACKED l2cap_command_header; 80 81 #define L2CAP_COMMAND_REJECT_RSP 0x01 82 typedef struct { 83 enum : uint16 { 84 REJECTED_NOT_UNDERSTOOD = 0x0000, 85 REJECTED_MTU_EXCEEDED = 0x0001, 86 REJECTED_INVALID_CID = 0x0002, 87 /* 0x0003-0xffff: reserved */ 88 }; uint16 reason; 89 /* data may follow */ 90 } _PACKED l2cap_command_reject; 91 92 typedef union { 93 struct { 94 uint16 mtu; /* actual signaling MTU */ 95 } _PACKED mtu_exceeded; 96 struct { 97 uint16 scid; /* source (local) CID */ 98 uint16 dcid; /* destination (remote) CID */ 99 } _PACKED invalid_cid; 100 } l2cap_command_reject_data; 101 102 103 #define L2CAP_CONNECTION_REQ 0x02 104 typedef struct { 105 uint16 psm; 106 uint16 scid; /* source channel ID */ 107 } _PACKED l2cap_connection_req; 108 109 #define L2CAP_CONNECTION_RSP 0x03 110 typedef struct { 111 uint16 dcid; /* destination channel ID */ 112 uint16 scid; /* source channel ID */ 113 enum : uint16 { 114 RESULT_SUCCESS = 0x0000, 115 RESULT_PENDING = 0x0001, 116 RESULT_PSM_NOT_SUPPORTED = 0x0002, 117 RESULT_SECURITY_BLOCK = 0x0003, 118 RESULT_NO_RESOURCES = 0x0004, 119 RESULT_INVALID_SCID = 0x0005, 120 RESULT_SCID_ALREADY_ALLOCATED = 0x0006, 121 /* 0x0007-0xffff: reserved */ 122 }; uint16 result; 123 enum : uint16 { 124 NO_STATUS_INFO = 0x0000, 125 STATUS_AUTHENTICATION_PENDING = 0x0001, 126 STATUS_AUTHORIZATION_PENDING = 0x0002, 127 /* 0x0003-0xffff: reserved */ 128 }; uint16 status; /* only defined if result = pending */ 129 } _PACKED l2cap_connection_rsp; 130 131 132 #define L2CAP_CONFIGURATION_REQ 0x04 133 typedef struct { 134 uint16 dcid; /* destination channel ID */ 135 uint16 flags; 136 /* options may follow */ 137 } _PACKED l2cap_configuration_req; 138 139 #define L2CAP_CONFIGURATION_RSP 0x05 140 typedef struct { 141 uint16 scid; /* source channel ID */ 142 uint16 flags; 143 #define L2CAP_CFG_FLAG_CONTINUATION 0x0001 144 enum : uint16 { 145 RESULT_SUCCESS = 0x0000, 146 RESULT_UNACCEPTABLE_PARAMS = 0x0001, 147 RESULT_REJECTED = 0x0002, 148 RESULT_UNKNOWN_OPTION = 0x0003, 149 RESULT_PENDING = 0x0004, 150 RESULT_FLOW_SPEC_REJECTED = 0x0005, 151 /* 0x0006-0xffff: reserved */ 152 }; uint16 result; 153 /* options may follow */ 154 } _PACKED l2cap_configuration_rsp; 155 156 typedef struct { 157 enum : uint8 { 158 OPTION_MTU = 0x01, 159 OPTION_FLUSH_TIMEOUT = 0x02, 160 OPTION_QOS = 0x03, 161 162 OPTION_HINT_BIT = 0x80, 163 }; uint8 type; 164 uint8 length; 165 /* value follows */ 166 } _PACKED l2cap_configuration_option; 167 168 typedef struct { 169 uint8 flags; /* reserved for future use */ 170 uint8 service_type; /* 1 = best effort */ 171 uint32 token_rate; /* average bytes per second */ 172 uint32 token_bucket_size; /* max burst bytes */ 173 uint32 peak_bandwidth; /* bytes per second */ 174 uint32 access_latency; /* microseconds */ 175 uint32 delay_variation; /* microseconds */ 176 } _PACKED l2cap_qos; 177 178 typedef union { 179 uint16 mtu; 180 uint16 flush_timeout; 181 l2cap_qos qos; 182 } l2cap_configuration_option_value; 183 184 185 #define L2CAP_DISCONNECTION_REQ 0x06 186 typedef struct { 187 uint16 dcid; /* destination channel ID */ 188 uint16 scid; /* source channel ID */ 189 } _PACKED l2cap_disconnection_req; 190 191 #define L2CAP_DISCONNECTION_RSP 0x07 192 typedef l2cap_disconnection_req l2cap_disconnection_rsp; 193 194 195 #define L2CAP_ECHO_REQ 0x08 196 #define L2CAP_ECHO_RSP 0x09 197 198 #define L2CAP_MAX_ECHO_SIZE \ 199 (L2CAP_MTU_MAXIMUM - sizeof(l2cap_command_header)) 200 201 202 #define L2CAP_INFORMATION_REQ 0x0a 203 typedef struct { 204 enum : uint16 { 205 TYPE_CONNECTIONLESS_MTU = 0x0001, 206 TYPE_EXTENDED_FEATURES = 0x0002, 207 TYPE_FIXED_CHANNELS = 0x0003, 208 /* 0x0004-0xffff: reserved */ 209 }; uint16 type; 210 } _PACKED l2cap_information_req; 211 212 #define L2CAP_INFORMATION_RSP 0x0b 213 typedef struct { 214 uint16 type; 215 enum : uint16 { 216 RESULT_SUCCESS = 0x0000, 217 RESULT_NOT_SUPPORTED = 0x0001, 218 }; uint16 result; 219 /* data may follow */ 220 } _PACKED l2cap_information_rsp; 221 222 typedef union { 223 uint16 mtu; 224 uint32 extended_features; 225 } _PACKED l2cap_information_rsp_data; 226 227 228 #endif /* _L2CAP_H_ */ 229