1little_endian_packets 2 3checksum Fcs : 16 "l2cap/" 4 5packet BasicFrame { 6 _size_(_payload_) : 16, 7 channel_id : 16, 8 _payload_, 9} 10 11packet BasicFrameWithFcs { 12 _checksum_start_(fcs), 13 _size_(_payload_) : 16, 14 channel_id : 16, 15 _payload_ : [+2*8], // Include Fcs in the _size_ 16 fcs : Fcs, 17} 18 19enum Continuation : 1 { 20 END = 0, 21 CONTINUE = 1, 22} 23 24// ChannelId 2 is connectionless 25packet GroupFrame : BasicFrame (channel_id = 0x02) { 26 psm : 16, 27 _payload_, 28} 29 30enum FrameType : 1 { 31 I_FRAME = 0, 32 S_FRAME = 1, 33} 34 35enum SupervisoryFunction : 2 { 36 RECEIVER_READY = 0, 37 REJECT = 1, 38 RECEIVER_NOT_READY = 2, 39 SELECT_REJECT = 3, 40} 41 42enum RetransmissionDisable : 1 { 43 NORMAL = 0, 44 DISABLE = 1, 45} 46 47enum SegmentationAndReassembly : 2 { 48 UNSEGMENTED = 0, 49 START = 1, 50 END = 2, 51 CONTINUATION = 3, 52} 53 54packet StandardFrame : BasicFrame { 55 frame_type : FrameType, 56 _body_, 57} 58 59packet StandardFrameWithFcs : BasicFrameWithFcs { 60 frame_type : FrameType, 61 _body_, 62} 63 64group StandardSupervisoryControl { 65 _fixed_ = 0 : 1, 66 s : SupervisoryFunction, 67 _reserved_ : 3, 68 r : RetransmissionDisable, 69 req_seq : 6, 70 _reserved_ : 2, 71} 72 73group StandardInformationControl { 74 tx_seq : 6, 75 r : RetransmissionDisable, 76 req_seq : 6, 77 sar : SegmentationAndReassembly, 78} 79 80packet StandardSupervisoryFrame : StandardFrame (frame_type = S_FRAME) { 81 StandardSupervisoryControl, 82} 83 84packet StandardSupervisoryFrameWithFcs : StandardFrameWithFcs (frame_type = S_FRAME) { 85 StandardSupervisoryControl, 86} 87 88packet StandardInformationFrame : StandardFrame (frame_type = I_FRAME) { 89 StandardInformationControl, 90 _payload_, 91} 92 93packet StandardInformationFrameWithFcs : StandardFrameWithFcs (frame_type = I_FRAME) { 94 StandardInformationControl, 95 _payload_, 96} 97 98packet StandardInformationStartFrame : StandardInformationFrame (sar = START) { 99 l2cap_sdu_length : 16, 100 _payload_, 101} 102 103packet StandardInformationStartFrameWithFcs : StandardInformationFrameWithFcs (sar = START) { 104 l2cap_sdu_length : 16, 105 _payload_, 106} 107 108enum Poll : 1 { 109 NOT_SET = 0, 110 POLL = 1, 111} 112 113enum Final : 1 { 114 NOT_SET = 0, 115 POLL_RESPONSE = 1, 116} 117 118group EnhancedSupervisoryControl { 119 _fixed_ = 0 : 1, 120 s : SupervisoryFunction, 121 p : Poll, 122 _reserved_ : 2, 123 f : Final, 124 req_seq : 6, 125 _reserved_ : 2, 126} 127 128group EnhancedInformationControl { 129 tx_seq : 6, 130 f : Final, 131 req_seq : 6, 132 sar : SegmentationAndReassembly, 133} 134 135packet EnhancedSupervisoryFrame : StandardFrame (frame_type = S_FRAME) { 136 EnhancedSupervisoryControl, 137} 138 139packet EnhancedSupervisoryFrameWithFcs : StandardFrameWithFcs (frame_type = S_FRAME) { 140 EnhancedSupervisoryControl, 141} 142 143packet EnhancedInformationFrame : StandardFrame (frame_type = I_FRAME) { 144 EnhancedInformationControl, 145 _payload_, 146} 147 148packet EnhancedInformationFrameWithFcs : StandardFrameWithFcs (frame_type = I_FRAME) { 149 EnhancedInformationControl, 150 _payload_, 151} 152 153packet EnhancedInformationStartFrame : EnhancedInformationFrame (sar = START) { 154 l2cap_sdu_length : 16, 155 _payload_, 156} 157 158packet EnhancedInformationStartFrameWithFcs : EnhancedInformationFrameWithFcs (sar = START) { 159 l2cap_sdu_length : 16, 160 _payload_, 161} 162 163group ExtendedSupervisoryControl { 164 f : Final, 165 req_seq : 14, 166 s : SupervisoryFunction, 167 p : Poll, 168 _reserved_ : 5, 169 _reserved_ : 8, 170} 171 172group ExtendedInformationControl { 173 f : Final, 174 req_seq : 14, 175 sar : SegmentationAndReassembly, 176 tx_seq : 14, 177} 178 179packet ExtendedSupervisoryFrame : StandardFrame (frame_type = S_FRAME) { 180 ExtendedSupervisoryControl, 181} 182 183packet ExtendedSupervisoryFrameWithFcs : StandardFrameWithFcs (frame_type = S_FRAME) { 184 ExtendedSupervisoryControl, 185} 186 187packet ExtendedInformationFrame : StandardFrame (frame_type = I_FRAME) { 188 ExtendedInformationControl, 189 _payload_, 190} 191 192packet ExtendedInformationFrameWithFcs : StandardFrameWithFcs (frame_type = I_FRAME) { 193 ExtendedInformationControl, 194 _payload_, 195} 196 197packet ExtendedInformationStartFrame : ExtendedInformationFrame (sar = START) { 198 l2cap_sdu_length : 16, 199 _payload_, 200} 201 202packet ExtendedInformationStartFrameWithFcs : ExtendedInformationFrameWithFcs (sar = START) { 203 l2cap_sdu_length : 16, 204 _payload_, 205} 206 207packet FirstLeInformationFrame : BasicFrame { 208 l2cap_sdu_length : 16, 209 _payload_, 210} 211 212enum CommandCode : 8 { 213 COMMAND_REJECT = 0x01, 214 CONNECTION_REQUEST = 0x02, 215 CONNECTION_RESPONSE = 0x03, 216 CONFIGURATION_REQUEST = 0x04, 217 CONFIGURATION_RESPONSE = 0x05, 218 DISCONNECTION_REQUEST = 0x06, 219 DISCONNECTION_RESPONSE = 0x07, 220 ECHO_REQUEST = 0x08, 221 ECHO_RESPONSE = 0x09, 222 INFORMATION_REQUEST = 0x0A, 223 INFORMATION_RESPONSE = 0x0B, 224 CREATE_CHANNEL_REQUEST = 0x0C, 225 CREATE_CHANNEL_RESPONSE = 0x0D, 226 MOVE_CHANNEL_REQUEST = 0x0E, 227 MOVE_CHANNEL_RESPONSE = 0x0F, 228 MOVE_CHANNEL_CONFIRMATION_REQUEST = 0x10, 229 MOVE_CHANNEL_CONFIRMATION_RESPONSE = 0x11, 230} 231 232packet ControlFrame : BasicFrame (channel_id = 0x0001) { 233 _payload_, 234} 235 236packet Control { 237 code : CommandCode, 238 identifier : 8, 239 _size_(_payload_) : 16, 240 _payload_, 241} 242 243enum CommandRejectReason : 16 { 244 COMMAND_NOT_UNDERSTOOD = 0x0000, 245 SIGNALING_MTU_EXCEEDED = 0x0001, 246 INVALID_CID_IN_REQUEST = 0x0002, 247} 248 249packet CommandReject : Control (code = COMMAND_REJECT) { 250 reason : CommandRejectReason, 251 _body_, 252} 253 254packet CommandRejectNotUnderstood : CommandReject (reason = COMMAND_NOT_UNDERSTOOD) { 255} 256 257packet CommandRejectMtuExceeded : CommandReject (reason = SIGNALING_MTU_EXCEEDED) { 258 actual_mtu : 16, 259} 260 261packet CommandRejectInvalidCid : CommandReject (reason = INVALID_CID_IN_REQUEST) { 262 local_channel : 16, // Relative to the sender of the CommandReject 263 remote_channel : 16, 264} 265 266packet ConnectionRequest : Control (code = CONNECTION_REQUEST) { 267 psm : 16, 268 source_cid : 16, 269} 270 271enum ConnectionResponseResult : 16 { 272 SUCCESS = 0x0000, 273 PENDING = 0x0001, 274 PSM_NOT_SUPPORTED = 0x0002, 275 SECURITY_BLOCK = 0x0003, 276 NO_RESOURCES_AVAILABLE = 0x0004, 277 INVALID_CID = 0x0006, 278 SOURCE_CID_ALREADY_ALLOCATED = 0x0007, 279} 280 281enum ConnectionResponseStatus : 16 { 282 NO_FURTHER_INFORMATION_AVAILABLE = 0x0000, 283 AUTHENTICATION_PENDING = 0x0001, 284 AUTHORIZATION_PENDING = 0x0002, 285} 286 287packet ConnectionResponse : Control (code = CONNECTION_RESPONSE) { 288 destination_cid : 16, 289 source_cid : 16, 290 result : ConnectionResponseResult, 291 status : ConnectionResponseStatus, 292} 293 294enum ConfigurationOptionType : 7 { 295 MTU = 0x01, 296 FLUSH_TIMEOUT = 0x02, 297 QUALITY_OF_SERVICE = 0x03, 298 RETRANSMISSION_AND_FLOW_CONTROL = 0x04, 299 FRAME_CHECK_SEQUENCE = 0x05, 300 EXTENDED_FLOW_SPECIFICATION = 0x06, 301 EXTENDED_WINDOW_SIZE = 0x07, 302} 303 304enum ConfigurationOptionIsHint : 1 { 305 OPTION_MUST_BE_RECOGNIZED = 0, 306 OPTION_IS_A_HINT = 1, 307} 308 309struct ConfigurationOption { 310 type : ConfigurationOptionType, 311 is_hint : ConfigurationOptionIsHint, 312 length : 8, 313 _body_, 314} 315 316struct MtuConfigurationOption : ConfigurationOption (type = MTU, length = 2) { 317 mtu : 16, 318} 319 320struct FlushTimeoutConfigurationOption : ConfigurationOption (type = FLUSH_TIMEOUT, length = 2) { 321 flush_timeout : 16, 322} 323 324enum QosServiceType : 8 { 325 NO_TRAFFIC = 0x00, 326 BEST_EFFORT = 0x01, // Default 327 GUARANTEED = 0x02, 328} 329 330struct QualityOfServiceConfigurationOption : ConfigurationOption (type = QUALITY_OF_SERVICE, length = 22) { 331 _reserved_ : 8, // Flags 332 service_type : QosServiceType, 333 token_rate : 32, // 0 = ignore, 0xffffffff = max available 334 token_bucket_size : 32, // 0 = ignore, 0xffffffff = max available 335 peak_bandwidth : 32, // Octets/second 0 = ignore 336 latency : 32, // microseconds 0xffffffff = ignore 337 delay_variation : 32, // microseconds 0xffffffff = ignore 338} 339 340enum RetransmissionAndFlowControlModeOption : 8 { 341 L2CAP_BASIC = 0x00, 342 RETRANSMISSION = 0x01, 343 FLOW_CONTROL = 0x02, 344 ENHANCED_RETRANSMISSION = 0x03, 345 STREAMING = 0x04, 346} 347 348 349struct RetransmissionAndFlowControlConfigurationOption : ConfigurationOption (type = RETRANSMISSION_AND_FLOW_CONTROL, length = 9) { 350 mode : RetransmissionAndFlowControlModeOption, 351 tx_window_size : 8, // 1-32 for Flow Control and Retransmission, 1-63 for Enhanced 352 max_transmit : 8, 353 retransmission_time_out : 16, 354 monitor_time_out : 16, 355 maximum_pdu_size : 16, 356} 357 358enum FcsType : 8 { 359 NO_FCS = 0, 360 DEFAULT = 1, // 16-bit FCS 361} 362 363struct FrameCheckSequenceOption : ConfigurationOption (type = FRAME_CHECK_SEQUENCE, length = 1) { 364 fcs_type : FcsType, 365} 366 367 368struct ExtendedFlowSpecificationOption : ConfigurationOption (type = EXTENDED_FLOW_SPECIFICATION, length = 16) { 369 identifier : 8, // Default 0x01, must be 0x01 for Extended Flow-Best-Effort 370 service_type : QosServiceType, 371 maximum_sdu_size : 16, // Octets 372 sdu_interarrival_time : 32, // in microseconds 373 access_latency : 32, // in microseconds, without HCI and stack overheads 374 flush_timeout : 32, // in microseconds 0x0 = no retransmissions 0xFFFFFFFF = never flushed 375} 376 377struct ExtendedWindowSizeOption : ConfigurationOption (type = EXTENDED_WINDOW_SIZE, length = 2) { 378 max_window_size : 16, // 0x0000 = Valid for streaming, 0x0001-0x3FFF Valid for Enhanced Retransmission 379} 380 381packet ConfigurationRequest : Control (code = CONFIGURATION_REQUEST) { 382 destination_cid : 16, 383 continuation : Continuation, 384 _reserved_ : 15, 385 config : ConfigurationOption[], 386} 387 388enum ConfigurationResponseResult : 16 { 389 SUCCESS = 0x0000, 390 UNACCEPTABLE_PARAMETERS = 0x0001, 391 REJECTED = 0x0002, 392 UNKNOWN_OPTIONS = 0x0003, 393 PENDING = 0x0004, 394 FLOW_SPEC_REJECTED = 0x0005, 395} 396 397packet ConfigurationResponse : Control (code = CONFIGURATION_RESPONSE) { 398 source_cid : 16, 399 continuation : Continuation, 400 _reserved_ : 15, 401 result : ConfigurationResponseResult, 402 config : ConfigurationOption[], 403} 404 405packet DisconnectionRequest : Control (code = DISCONNECTION_REQUEST) { 406 destination_cid : 16, 407 source_cid : 16, 408} 409 410packet DisconnectionResponse : Control (code = DISCONNECTION_RESPONSE) { 411 destination_cid : 16, 412 source_cid : 16, 413} 414 415packet EchoRequest : Control (code = ECHO_REQUEST) { 416 _payload_, // Optional and implementation specific 417} 418 419packet EchoResponse : Control (code = ECHO_RESPONSE) { 420 _payload_, // Optional and implementation specific 421} 422 423enum InformationRequestInfoType : 16 { 424 CONNECTIONLESS_MTU = 0x0001, 425 EXTENDED_FEATURES_SUPPORTED = 0x0002, 426 FIXED_CHANNELS_SUPPORTED = 0x0003, 427} 428 429packet InformationRequest : Control (code = INFORMATION_REQUEST) { 430 info_type : InformationRequestInfoType, 431} 432 433enum InformationRequestResult : 16 { 434 SUCCESS = 0x0000, 435 NOT_SUPPORTED = 0x0001, 436} 437 438packet InformationResponse : Control (code = INFORMATION_RESPONSE) { 439 info_type : InformationRequestInfoType, 440 result : InformationRequestResult, 441 _body_, 442} 443 444packet InformationResponseConnectionlessMtu : InformationResponse (info_type = CONNECTIONLESS_MTU) { 445 connectionless_mtu : 16, 446} 447 448packet InformationResponseExtendedFeatures : InformationResponse (info_type = EXTENDED_FEATURES_SUPPORTED) { 449 // ExtendedFeatureMask : 32, 450 flow_control_mode : 1, 451 retransmission_mode : 1, 452 bi_directional_qoS : 1, 453 enhanced_retransmission_mode : 1, 454 streaming_mode : 1, 455 fcs_option : 1, 456 extended_flow_specification_for_br_edr : 1, 457 fixed_channels : 1, 458 extended_window_size : 1, 459 unicast_connectionless_data_reception : 1, 460 _reserved_ : 22, 461} 462 463packet InformationResponseFixedChannels : InformationResponse (info_type = FIXED_CHANNELS_SUPPORTED) { 464 fixed_channels : 64, // bit 0 must be 0, bit 1 must be 1, all others 1 = supported 465} 466 467packet CreateChannelRequest : Control (code = CREATE_CHANNEL_REQUEST) { 468 psm : 16, 469 source_cid : 16, 470 controller_id : 8, 471} 472 473enum CreateChannelResponseResult : 16 { 474 SUCCESS = 0x0000, 475 PENDING = 0x0001, 476 PSM_NOT_SUPPORTED = 0x0002, 477 SECURITY_BLOCK = 0x0003, 478 NO_RESOURCES_AVAILABLE = 0x0004, 479 CONTROLLER_ID_NOT_SUPPORTED = 0x0005, 480 INVALID_CID = 0x0006, 481 SOURCE_CID_ALREADY_ALLOCATED = 0x0007, 482} 483 484enum CreateChannelResponseStatus : 16 { 485 NO_FURTHER_INFORMATION_AVAILABLE = 0x0000, 486 AUTHENTICATION_PENDING = 0x0001, 487 AUTHORIZATION_PENDING = 0x0002, 488} 489 490packet CreateChannelResponse : Control (code = CREATE_CHANNEL_RESPONSE) { 491 destination_cid : 16, 492 source_cid : 16, 493 result : CreateChannelResponseResult, 494 status : CreateChannelResponseStatus, 495} 496 497// AMP Only ? 498packet MoveChannelRequest : Control (code = MOVE_CHANNEL_REQUEST) { 499 initiator_cid : 16, 500 dest_controller_id : 8, 501} 502 503enum MoveChannelResponseResult : 16 { 504 SUCCESS = 0x0000, 505 PENDING = 0x0001, 506 CONTROLLER_ID_NOT_SUPPORTED = 0x0002, 507 NEW_CONTROLLER_ID_IS_SAME = 0x0003, 508 CONFIGURATION_NOT_SUPPORTED = 0x0004, 509 CHANNEL_COLLISION = 0x0005, 510 CHANNEL_NOT_ALLOWED_TO_BE_MOVED = 0x0006, 511} 512 513packet MoveChannelResponse : Control (code = MOVE_CHANNEL_RESPONSE) { 514 initiator_cid : 16, 515 result : MoveChannelResponseResult, 516} 517 518enum MoveChannelConfirmationResult : 16 { 519 SUCCESS = 0x0000, 520 FAILURE = 0x0001, 521} 522 523packet MoveChannelConfirmationRequest : Control (code = MOVE_CHANNEL_CONFIRMATION_REQUEST) { 524 initiator_cid : 16, 525 result : MoveChannelConfirmationResult, 526} 527 528packet MoveChannelConfirmationResponse : Control (code = MOVE_CHANNEL_CONFIRMATION_RESPONSE) { 529 initiator_cid : 16, 530} 531 532enum LeCommandCode : 8 { 533 COMMAND_REJECT = 0x01, 534 DISCONNECTION_REQUEST = 0x06, 535 DISCONNECTION_RESPONSE = 0x07, 536 CONNECTION_PARAMETER_UPDATE_REQUEST = 0x12, 537 CONNECTION_PARAMETER_UPDATE_RESPONSE = 0x13, 538 LE_CREDIT_BASED_CONNECTION_REQUEST = 0x14, 539 LE_CREDIT_BASED_CONNECTION_RESPONSE = 0x15, 540 LE_FLOW_CONTROL_CREDIT = 0x16, 541} 542 543packet LeControlFrame : BasicFrame (channel_id = 0x0005) { 544 _payload_, 545} 546 547packet LeControl { 548 code : LeCommandCode, 549 identifier : 8, // Must be non-zero 550 _size_(_payload_) : 16, 551 _payload_, 552} 553 554 555packet LeCommandReject : LeControl (code = COMMAND_REJECT) { 556 reason : CommandRejectReason, 557 _payload_, 558} 559 560packet LeCommandRejectNotUnderstood : LeCommandReject (reason = COMMAND_NOT_UNDERSTOOD) { 561} 562 563packet LeCommandRejectMtuExceeded : LeCommandReject (reason = SIGNALING_MTU_EXCEEDED) { 564 actual_mtu : 16, 565} 566 567packet LeCommandRejectInvalidCid : LeCommandReject (reason = INVALID_CID_IN_REQUEST) { 568 local_channel : 16, // Relative to the sender of the CommandReject 569 remote_channel : 16, 570} 571 572packet LeDisconnectionRequest : LeControl (code = DISCONNECTION_REQUEST) { 573 destination_cid : 16, 574 source_cid : 16, 575} 576 577packet LeDisconnectionResponse : LeControl (code = DISCONNECTION_RESPONSE) { 578 destination_cid : 16, 579 source_cid : 16, 580} 581 582packet ConnectionParameterUpdateRequest : LeControl (code = CONNECTION_PARAMETER_UPDATE_REQUEST) { 583 interval_min : 16, 584 interval_max : 16, 585 slave_latency : 16, 586 timeout_multiplier : 16, 587} 588 589enum ConnectionParameterUpdateResponseResult : 16 { 590 ACCEPTED = 0, 591 REJECTED = 1, 592} 593 594packet ConnectionParameterUpdateResponse : LeControl (code = CONNECTION_PARAMETER_UPDATE_RESPONSE) { 595 result : ConnectionParameterUpdateResponseResult, 596} 597 598packet LeCreditBasedConnectionRequest : LeControl (code = LE_CREDIT_BASED_CONNECTION_REQUEST) { 599 le_psm : 16, // 0x0001-0x007F Fixed, 0x0080-0x00FF Dynamic 600 source_cid : 16, 601 mtu : 16, 602 mps : 16, 603 initial_credits : 16, 604} 605 606enum LeCreditBasedConnectionResponseResult : 16 { 607 SUCCESS = 0x0000, 608 LE_PSM_NOT_SUPPORTED = 0x0002, 609 NO_RESOURCES_AVAILABLE = 0x0004, 610 INSUFFICIENT_AUTHENTICATION = 0x0005, 611 INSUFFICIENT_AUTHORIZATION = 0x0006, 612 INSUFFICIENT_ENCRYPTION_KEY_SIZE = 0x0007, 613 INSUFFICIENT_ENCRYPTION = 0x0008, 614 INVALID_SOURCE_CID = 0x0009, 615 SOURCE_CID_ALREADY_ALLOCATED = 0x000A, 616 UNACCEPTABLE_PARAMETERS = 0x000B, 617} 618 619packet LeCreditBasedConnectionResponse : LeControl (code = LE_CREDIT_BASED_CONNECTION_RESPONSE) { 620 destination_cid : 16, 621 mtu : 16, 622 mps : 16, 623 initial_credits : 16, 624 result : LeCreditBasedConnectionResponseResult, 625} 626 627packet LeFlowControlCredit : LeControl (code = LE_FLOW_CONTROL_CREDIT) { 628 cid : 16, // Receiver's destination CID 629 credits : 16, 630} 631 632