• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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