1 #ifndef _L2CC_PDU_H_
2 #define _L2CC_PDU_H_
3 
4 /**
5  ****************************************************************************************
6  * @addtogroup L2CC_PDU L2Cap Controller PDU generator/extractor
7  * @ingroup L2CC
8  * @brief This module is in charge to pack or unpack L2CAP packets
9  *
10  * @{
11  ****************************************************************************************
12  */
13 
14 /*
15  * INCLUDE FILES
16  ****************************************************************************************
17  */
18 #include "co_bt.h"
19 #include "gap.h"
20 #include "att.h"
21 #include "compiler.h"
22 
23 /*
24  * MACROS
25  ****************************************************************************************
26  */
27 
28 
29 /*
30  * DEFINES
31  ****************************************************************************************
32  */
33 
34 /// Minimal authorized MTU value (defined by Bluetooth SIG)
35 #define L2C_MIN_LE_MTUSIG                   (23)
36 
37 /// L2CAP mode supported for BLE - only mode accepted
38 #define L2C_MODE_BASIC_L2CAP                (0x00)
39 
40 /// Packet partition
41 #define L2C_CID_LEN                         (2)
42 #define L2C_LENGTH_LEN                      (2)
43 #define L2C_CODE_LEN                        (1)
44 #define L2C_HEADER_LEN                      (L2C_CID_LEN + L2C_LENGTH_LEN)
45 #define L2C_SDU_LEN                         (2)
46 #define L2C_LECB_HEADER_LEN                 (L2C_HEADER_LEN + L2C_SDU_LEN)
47 
48 /// Maximum credit
49 #define L2C_LECB_MAX_CREDIT     0xFFFF
50 
51 
52 /* result for connection parameter update response */
53 #define L2C_CONN_PARAM_ACCEPT               0x0000
54 #define L2C_CONN_PARAM_REJECT               0x0001
55 
56 /* command reject reasons */
57 enum l2cc_pdu_err
58 {
59     L2C_CMD_NOT_UNDERSTOOD             = 0x0000,
60     L2C_MTU_SIG_EXCEEDED               = 0x0001,
61     L2C_INVALID_CID                    = 0x0002,
62 };
63 
64 /// Check if channel ID is within the correct range
65 #define L2C_IS_DYNAMIC_CID(cid) ((cid >= L2C_CID_DYN_MIN) && (cid <= L2C_CID_DYN_MAX))
66 
67 /// Check if LE PSM is within the correct range
68 #define L2C_IS_VALID_LEPSM(lepsm) (lepsm != L2C_LEPSM_RESERVED)
69 
70 /*
71  * ENUMERATIONS
72  ****************************************************************************************
73  */
74 
75 /** L2CAP LE PSM limits */
76 enum l2cc_lepsm_limits
77 {
78     /// Reserved
79     L2C_LEPSM_RESERVED                   = 0x0000,
80     /// Fixed minimum range SIG assigned
81     L2C_LEPSM_FIXED_MIN                  = 0x0001,
82     /// Fixed maximum range SIG assigned
83     L2C_LEPSM_FIXED_MAX                  = 0x007F,
84     /// Dynamic minimum range SIG assigned
85     L2C_LEPSM_DYN_MIN                    = 0x0080,
86     /// Dynamic maximum range SIG assigned
87     L2C_LEPSM_DYN_MAX                    = 0x00FF,
88     /// Reserved minimum range SIG assigned
89     L2C_LEPSM_RSV_MIN                    = 0x0100,
90     /// Reserved maximum range SIG assigned
91     L2C_LEPSM_RSV_MAX                    = 0xFFFF,
92 };
93 
94 /** L2CAP channels id */
95 enum l2cc_cid
96 {
97     /// Reserved channel id
98     L2C_CID_RESERVED                   = 0x0000,
99     /// Attribute channel id
100     L2C_CID_ATTRIBUTE                  = 0x0004,
101     /// Signaling channel id
102     L2C_CID_LE_SIGNALING               = 0x0005,
103     /// Security channel id
104     L2C_CID_SECURITY                   = 0x0006,
105     /// Dynamically allocated minimum range
106     L2C_CID_DYN_MIN                    = 0x0040,
107     /// Dynamically allocated maximum range
108     L2C_CID_DYN_MAX                    = 0x007F,
109 };
110 
111 
112 /// signaling codes
113 enum l2cc_signal_code
114 {
115     /// Reserved code
116     L2C_CODE_RESERVED                  = 0x00,
117     /// Reject request
118     L2C_CODE_REJECT                    = 0x01,
119     /// Connection request
120     L2C_CODE_CONNECTION_REQ            = 0x02,
121     /// Connection response
122     L2C_CODE_CONNECTION_RESP           = 0x03,
123     /// Configuration request
124     L2C_CODE_CONFIGURATION_REQ         = 0x04,
125     /// Configuration response
126     L2C_CODE_CONFIGURATION_RESP        = 0x05,
127     /// Disconnection request
128     L2C_CODE_DISCONNECTION_REQ         = 0x06,
129     /// Disconnection response
130     L2C_CODE_DISCONNECTION_RESP        = 0x07,
131     /// Echo request
132     L2C_CODE_ECHO_REQ                  = 0x08,
133     /// Echo response
134     L2C_CODE_ECHO_RESP                 = 0x09,
135     /// Information request
136     L2C_CODE_INFORMATION_REQ           = 0x0A,
137     /// Information response
138     L2C_CODE_INFORMATION_RESP          = 0x0B,
139     /// Create channel request
140     L2C_CODE_CREATE_CHANNEL_REQ        = 0x0C,
141     /// Create channel response
142     L2C_CODE_CREATE_CHANNEL_RESP       = 0x0D,
143     /// Move channel request
144     L2C_CODE_MOVE_CHANNEL_REQ          = 0x0E,
145     /// Move channel response
146     L2C_CODE_MOVE_CHANNEL_RESP         = 0x0F,
147     /// Move channel confirmation
148     L2C_CODE_MOVE_CHANNEL_CFM          = 0x10,
149     /// Move channel confirmation response
150     L2C_CODE_MOVE_CHANNEL_CFM_RESP     = 0x11,
151     /// Connection Parameter Update Request
152     L2C_CODE_CONN_PARAM_UPD_REQ        = 0x12,
153     /// Connection Parameter Update Response
154     L2C_CODE_CONN_PARAM_UPD_RESP       = 0x13,
155     /// LE Credit Based Connection request
156     L2C_CODE_LE_CB_CONN_REQ            = 0x14,
157     /// LE Credit Based Connection response
158     L2C_CODE_LE_CB_CONN_RESP           = 0x15,
159     /// LE Flow Control Credit
160     L2C_CODE_LE_FLOW_CONTROL_CREDIT    = 0x16,
161 
162     /// max number of signaling codes
163     L2C_CODE_SIGNALING_MAX
164 };
165 
166 
167 /// security codes
168 enum l2cc_security_code
169 {
170     /// Pairing Request
171     L2C_CODE_PAIRING_REQUEST              = 0x01,
172     /// Pairing Response
173     L2C_CODE_PAIRING_RESPONSE             = 0x02,
174     /// Pairing Confirm
175     L2C_CODE_PAIRING_CONFIRM              = 0x03,
176     /// Pairing Random
177     L2C_CODE_PAIRING_RANDOM               = 0x04,
178     /// Pairing Failed
179     L2C_CODE_PAIRING_FAILED               = 0x05,
180     /// Encryption Information
181     L2C_CODE_ENCRYPTION_INFORMATION       = 0x06,
182     /// Master Identification
183     L2C_CODE_MASTER_IDENTIFICATION        = 0x07,
184     /// Identity Information
185     L2C_CODE_IDENTITY_INFORMATION         = 0x08,
186     /// Identity Address Information
187     L2C_CODE_IDENTITY_ADDRESS_INFORMATION = 0x09,
188     /// Signing Information
189     L2C_CODE_SIGNING_INFORMATION          = 0x0A,
190     /// Security Request
191     L2C_CODE_SECURITY_REQUEST             = 0x0B,
192     // Pairing Public Keys
193     L2C_CODE_PUBLIC_KEY                   = 0x0C,
194     // Pairing DHKey Check
195     L2C_CODE_DHKEY_CHECK                  = 0x0D,
196     // Pairing Keypress Notification
197     L2C_CODE_KEYPRESS_NOTIFICATION        = 0x0E,
198     /// max number of security codes
199     L2C_CODE_SECURITY_MAX
200 };
201 
202 
203 /// attribute protocol PDU codes
204 enum l2cc_attribute_code
205 {
206     /// Error response
207     L2C_CODE_ATT_ERR_RSP            = 0x01,
208     /// Exchange MTU Request
209     L2C_CODE_ATT_MTU_REQ            = 0x02,
210     /// Exchange MTU Response
211     L2C_CODE_ATT_MTU_RSP            = 0x03,
212     /// Find Information Request
213     L2C_CODE_ATT_FIND_INFO_REQ      = 0x04,
214     /// Find Information Response
215     L2C_CODE_ATT_FIND_INFO_RSP      = 0x05,
216     /// Find By Type Value Request
217     L2C_CODE_ATT_FIND_BY_TYPE_REQ   = 0x06,
218     /// Find By Type Value Response
219     L2C_CODE_ATT_FIND_BY_TYPE_RSP   = 0x07,
220     /// Read By Type Request
221     L2C_CODE_ATT_RD_BY_TYPE_REQ     = 0x08,
222     /// Read By Type Response
223     L2C_CODE_ATT_RD_BY_TYPE_RSP     = 0x09,
224     /// Read Request
225     L2C_CODE_ATT_RD_REQ             = 0x0A,
226     /// Read Response
227     L2C_CODE_ATT_RD_RSP             = 0x0B,
228     /// Read Blob Request
229     L2C_CODE_ATT_RD_BLOB_REQ        = 0x0C,
230     /// Read Blob Response
231     L2C_CODE_ATT_RD_BLOB_RSP        = 0x0D,
232     /// Read Multiple Request
233     L2C_CODE_ATT_RD_MULT_REQ        = 0x0E,
234     /// Read Multiple Response
235     L2C_CODE_ATT_RD_MULT_RSP        = 0x0F,
236     /// Read by Group Type Request
237     L2C_CODE_ATT_RD_BY_GRP_TYPE_REQ = 0x10,
238     /// Read By Group Type Response
239     L2C_CODE_ATT_RD_BY_GRP_TYPE_RSP = 0x11,
240     /// Write Request
241     L2C_CODE_ATT_WR_REQ             = 0x12,
242     /// Write Response
243     L2C_CODE_ATT_WR_RSP             = 0x13,
244     /// Write Command
245     L2C_CODE_ATT_WR_CMD_INFO        = 0x14,
246     L2C_CODE_ATT_WR_CMD             = 0x52,
247     /// Signed Write Command
248     L2C_CODE_ATT_SIGN_WR_CMD_INFO   = 0x15,
249     L2C_CODE_ATT_SIGN_WR_CMD        = 0xD2,
250     /// Prepare Write Request
251     L2C_CODE_ATT_PREP_WR_REQ        = 0x16,
252     /// Prepare Write Response
253     L2C_CODE_ATT_PREP_WR_RSP        = 0x17,
254     /// Execute Write Request
255     L2C_CODE_ATT_EXE_WR_REQ         = 0x18,
256     /// Execute Write Response
257     L2C_CODE_ATT_EXE_WR_RSP         = 0x19,
258     /// Handle Value Notification
259     L2C_CODE_ATT_HDL_VAL_NTF        = 0x1B,
260     /// Handle Value Indication
261     L2C_CODE_ATT_HDL_VAL_IND        = 0x1D,
262     /// Handle Value Confirmation
263     L2C_CODE_ATT_HDL_VAL_CFM        = 0x1E,
264 
265     /// max number of security codes
266     L2C_CODE_ATT_MAX
267 };
268 
269 /// LE Connection oriented PDU codes
270 enum l2cc_le_connor_code
271 {
272     /// Data frame
273     L2C_CODE_CON_DATA            = 0x01,
274 
275     /// max number of connection oriented codes
276     L2C_CODE_CON_MAX
277 };
278 
279 /// Result values for LE Credit Based Connection Response
280 enum l2cc_cb_resp_value
281 {
282     /// connection successful
283     L2C_CB_CON_SUCCESS          = 0x0000,
284     /// Reserved
285     L2C_CB_CON_RSV1,
286     /// Connection refused - LE_PSM not supported
287     L2C_CB_CON_LEPSM_NOT_SUPP,
288     /// Reserved
289     L2C_CB_CON_RSV2,
290     /// Connection refused - no resources available
291     L2C_CB_CON_NO_RES_AVAIL,
292     /// Connection refused - insufficient authentication
293     L2C_CB_CON_INS_AUTH,
294     /// Connection refused - insufficient authorization
295     L2C_CB_CON_INS_AUTHOR,
296     /// Connection refused - insufficient encryption key size
297     L2C_CB_CON_INS_EKS,
298     /// Connection Refused - insufficient encryption
299     L2C_CB_CON_INS_ENCRYPTION,
300 
301     /* ESR 09 error codes */
302     /// Connection Refused - invalid Source CID
303     L2C_CB_CON_INVALID_SRC_CID,
304     /// Connection Refused - Source CID already allocated
305     L2C_CB_CON_SRC_CID_ALREADY_ALLOC,
306     /// Connection Refused - Unacceptable parameters
307     L2C_CB_CON_UNACCEPTABLE_PARAM
308 };
309 
310 /*
311  * TYPE DEFINITIONS
312  ****************************************************************************************
313  */
314 
315 /// Disconnection Request
316 struct l2cc_disconnection_req
317 {
318     /// Signaling code - 0x06
319     uint8_t  code;
320     /// Packet Identifier
321     uint8_t  pkt_id;
322     /// data length
323     uint16_t length;
324     /// Destination CID
325     uint16_t dcid;
326     /// Source CID
327     uint16_t scid;
328 };
329 
330 /// Disconnection Response
331 struct l2cc_disconnection_rsp
332 {
333     /// Signaling code - 0x07
334     uint8_t  code;
335     /// Packet Identifier
336     uint8_t  pkt_id;
337     /// data length
338     uint16_t length;
339     /// Destination CID
340     uint16_t dcid;
341     /// Source CID
342     uint16_t scid;
343 };
344 
345 /// Connection Parameter Update Request
346 struct l2cc_update_param_req
347 {
348     /// Signaling code - 0x12
349     uint8_t  code;
350     /// Packet Identifier
351     uint8_t  pkt_id;
352     /// data length
353     uint16_t length;
354     /// minimum value for the connection event interval
355     uint16_t intv_min;
356     /// maximum value for the connection event interval
357     uint16_t intv_max;
358     /// slave latency parameter
359     uint16_t latency;
360     /// connection timeout parameter
361     uint16_t timeout;
362 };
363 
364 /// Connection Parameter Update Response
365 struct l2cc_update_param_rsp
366 {
367     /// Signaling code - 0x13
368     uint8_t  code;
369     /// Packet Identifier
370     uint8_t  pkt_id;
371     /// data length
372     uint16_t length;
373     /// Result field indicates the response to the Connection Parameter Update Request
374     /// - 0x0000 Connection Parameters accepted
375     /// - 0x0001 Connection Parameters rejected
376     uint16_t response;
377 };
378 
379 /// LE Credit based connection request
380 struct l2cc_lecb_req
381 {
382     /// Signaling code - 0x14
383     uint8_t  code;
384     /// Packet Identifier
385     uint8_t  pkt_id;
386     /// data length
387     uint16_t length;
388     /// LE Protocol/Service Multiplexer
389     uint16_t le_psm;
390     /// Source CID
391     uint16_t scid;
392     /// Maximum Transmission Unit
393     uint16_t mtu;
394     /// Maximum PDU Size
395     uint16_t mps;
396     /// Initial credits
397     uint16_t initial_credits;
398 };
399 
400 /// LE Credit based connection response
401 struct l2cc_lecb_rsp
402 {
403     /// Signaling code - 0x15
404     uint8_t  code;
405     /// Packet Identifier
406     uint8_t  pkt_id;
407     /// data length
408     uint16_t length;
409     /// Destination CID
410     uint16_t dcid;
411     /// Maximum Transmission Unit
412     uint16_t mtu;
413     /// Maximum PDU Size
414     uint16_t mps;
415     /// Initial credits
416     uint16_t initial_credits;
417     /// Result
418     uint16_t result;
419 };
420 
421 /// LE Flow Control Credit
422 struct l2cc_le_flow_ctl_credit
423 {
424     /// Signaling code - 0x16
425     uint8_t  code;
426     /// Packet Identifier
427     uint8_t  pkt_id;
428     /// data length
429     uint16_t length;
430     /// CID
431     uint16_t cid;
432     /// Credits
433     uint16_t credits;
434 };
435 
436 /// Command Reject
437 struct l2cc_reject
438 {
439     /// Signaling code - 0x01
440     uint8_t  code;
441     /// Packet Identifier
442     uint8_t  pkt_id;
443     /// data length
444     uint16_t length;
445     /// The Reason field describes why the Request packet was rejected
446     /// - 0x0000 Command not understood
447     /// - 0x0001 Signaling MTU exceeded
448     /// - 0x0002 Invalid CID in request
449     uint16_t reason;
450     /// Optional parameters total length
451     uint16_t opt_len;
452     ///16-byte array for optional parameters
453     uint8_t opt[__ARRAY_EMPTY];
454 };
455 
456 
457 /// Pairing Request
458 struct l2cc_pairing_req
459 {
460     /// security code - 0x01
461     uint8_t     code;
462     /// IO Capability
463     uint8_t     iocap;
464     /// OOB data flag
465     uint8_t     oob;
466     /// AuthReq
467     uint8_t     auth;
468     /// Maximum Encryption Key Size
469     uint8_t     key_size;
470     /// Initiator Key Distribution
471     uint8_t     ikey_dist;
472     /// Responder Key Distribution
473     uint8_t     rkey_dist;
474 };
475 /// Pairing Response
476 struct l2cc_pairing_rsp
477 {
478     /// security code - 0x02
479     uint8_t     code;
480     /// IO Capability
481     uint8_t     iocap;
482     /// OOB data flag
483     uint8_t     oob;
484     /// AuthReq
485     uint8_t     auth;
486     /// Maximum Encryption Key Size
487     uint8_t     key_size;
488     /// Initiator Key Distribution
489     uint8_t     ikey_dist;
490     /// Responder Key Distribution
491     uint8_t     rkey_dist;
492 };
493 /// Pairing Confirm
494 struct l2cc_pairing_cfm
495 {
496     /// security code - 0x03
497     uint8_t     code;
498     ///Confirm value
499     uint8_t     cfm_val[CFM_LEN];
500 };
501 /// Pairing Random
502 struct l2cc_pairing_random
503 {
504     /// security code - 0x04
505     uint8_t     code;
506     ///Random value
507     uint8_t     random[RAND_VAL_LEN];
508 };
509 /// Pairing Failed
510 struct l2cc_pairing_failed
511 {
512     /// security code - 0x05
513     uint8_t     code;
514     /// The Reason field indicates why the pairing failed
515     uint8_t     reason;
516 };
517 /// Encryption Information
518 struct l2cc_encryption_inf
519 {
520     /// security code - 0x06
521     uint8_t     code;
522     ///16-byte array for LTK value
523     uint8_t     ltk[GAP_KEY_LEN];
524 };
525 /// Master Identification
526 struct l2cc_master_id
527 {
528     /// security code - 0x07
529     uint8_t     code;
530     /// key diversifier
531     uint16_t    ediv;
532     ///8-byte array for random number
533     uint8_t     nb[GAP_RAND_NB_LEN];
534 };
535 /// Identity Information
536 struct l2cc_identity_inf
537 {
538     /// security code - 0x08
539     uint8_t     code;
540     ///16-byte array for IRK value
541     uint8_t     irk[GAP_KEY_LEN];
542 };
543 /// Identity Address Information
544 struct l2cc_id_addr_inf
545 {
546     /// security code - 0x09
547     uint8_t     code;
548     /// BD Address Type
549     uint8_t     addr_type;
550     /// BD Address
551     bd_addr_t addr;
552 };
553 /// Signing Information
554 struct l2cc_signing_inf
555 {
556     /// security code - 0x0A
557     uint8_t     code;
558     ///16-byte array for CSRK value
559     uint8_t     csrk[GAP_KEY_LEN];
560 };
561 /// Security Request
562 struct l2cc_security_req
563 {
564     /// security code - 0x0B
565     uint8_t     code;
566     /// AuthReq
567     uint8_t     auth;
568 };
569 
570 /// Public Key (x,y)
571 struct l2cc_publc_key
572 {
573     /// security code - 0x0C
574     uint8_t     code;
575     /// X and Y co-ordinates of the Public Key
576     uint8_t x[GAP_P256_KEY_LEN];
577     uint8_t y[GAP_P256_KEY_LEN];
578 };
579 
580 /// DH Key Check
581 struct l2cc_dhkey_check
582 {
583     /// security code - 0x0D
584     uint8_t  code;
585     uint8_t check[DHKEY_CHECK_LEN];
586 };
587 /// Keypress Notification - PassKey method only
588 struct l2cc_keypress_noticication
589 {
590     /// security code - 0x0E
591     uint8_t  code;
592 
593     uint8_t notification_type;
594 };
595 
596 
597 /* Attribute protocol PDUs */
598 
599 /// Error response
600 struct l2cc_att_err_rsp
601 {
602     /// Error Response - 0x01
603     uint8_t     code;
604     /// The request that generated this error response
605     uint8_t     op_code;
606     /// The attribute handle that generated this error response
607     uint16_t    handle;
608     ///The reason why the request has generated an error response
609     uint8_t     reason;
610 };
611 
612 /// Exchange MTU Request
613 struct l2cc_att_mtu_req
614 {
615     /// Exchange MTU Request - 0x02
616     uint8_t     code;
617     /// Client Rx MTU size
618     uint16_t    mtu_size;
619 };
620 
621 /// Exchange MTU Response
622 struct l2cc_att_mtu_rsp
623 {
624     /// Exchange MTU Response - 0x03
625     uint8_t     code;
626     /// Server Rx MTU size
627     uint16_t    mtu_size;
628 };
629 
630 /// Find Information Request
631 struct l2cc_att_find_info_req
632 {
633     /// Find Information Request - 0x04
634     uint8_t     code;
635     /// First requested handle number
636     uint16_t    shdl;
637     /// Last requested handle number
638     uint16_t    ehdl;
639 };
640 
641 /// Find Information Response
642 struct l2cc_att_find_info_rsp
643 {
644     /// Find Information Response - 0x05
645     uint8_t     code;
646     /// The format of the information data.
647     uint8_t     format;
648     /// Data length
649     uint16_t    data_len;
650     ///The information data whose format is determined by the Format field
651     uint8_t     data[__ARRAY_EMPTY];
652 };
653 
654 /// Find By Type Value Request
655 struct l2cc_att_find_by_type_req
656 {
657     /// Find By Type Value Request - 0x06
658     uint8_t     code;
659     /// First requested handle number
660     uint16_t    shdl;
661     /// Last requested handle number
662     uint16_t    ehdl;
663     /// 2 octet UUID to find
664     uint16_t    type;
665     /// Attribute value length
666     uint16_t    val_len;
667     /// Attribute value to find
668     uint8_t     val[__ARRAY_EMPTY];
669 };
670 
671 /// Find By Type Value Response
672 struct l2cc_att_find_by_type_rsp
673 {
674     /// Find By Type Value Response - 0x07
675     uint8_t     code;
676     /// data length
677     uint16_t    data_len;
678     /// A list of 1 or more Handle Informations.
679     uint8_t     data[__ARRAY_EMPTY];
680 };
681 
682 /// Read By Type Request
683 struct l2cc_att_rd_by_type_req
684 {
685     /// Read By Type Request - 0x08
686     uint8_t     code;
687     /// Starting Handle
688     uint16_t    shdl;
689     /// Ending Handle
690     uint16_t    ehdl;
691     /// Attribute uuid length
692     uint16_t    uuid_len;
693     /// Attribute type uuid
694     uint8_t     uuid[__ARRAY_EMPTY];
695 };
696 
697 /// Read By Type Response
698 struct l2cc_att_rd_by_type_rsp
699 {
700     /// Read By Type Response - 0x09
701     uint8_t     code;
702     /// size of each attribute handle listed
703     uint8_t     each_len;
704     /// Attribute Data length
705     uint16_t    data_len;
706     /// A list of Attribute Data.
707     uint8_t     data[__ARRAY_EMPTY];
708 };
709 
710 /// Read Request
711 struct l2cc_att_rd_req
712 {
713     /// Read Request - 0x0A
714     uint8_t     code;
715     /// Attribute Handle
716     uint16_t    handle;
717 };
718 
719 /// Read Response
720 struct l2cc_att_rd_rsp
721 {
722     /// Read Response - 0x0B
723     uint8_t    code;
724     /// value length
725     uint16_t   value_len;
726     /// The value of the attribute with the handle given
727     uint8_t    value[__ARRAY_EMPTY];
728 };
729 
730 /// Read Blob Request
731 struct l2cc_att_rd_blob_req
732 {
733     /// Read Blob Request - 0x0C
734     uint8_t     code;
735     /// Attribute Handle
736     uint16_t    handle;
737     /// The offset of the first octet to be read
738     uint16_t    offset;
739 };
740 
741 /// Read Blob Response
742 struct l2cc_att_rd_blob_rsp
743 {
744     /// Read Blob Response - 0x0D
745     uint8_t    code;
746     /// value length
747     uint16_t   value_len;
748     /// Part of the value of the attribute with the handle given
749     uint8_t    value[__ARRAY_EMPTY];
750 };
751 
752 /// Read Multiple Request
753 struct l2cc_att_rd_mult_req
754 {
755     /// Read Multiple Request - 0x0E
756     uint8_t     code;
757     /// Number of handles
758     uint16_t    nb_handles;
759     /// A set of two or more attribute handles.
760     uint16_t    handles[__ARRAY_EMPTY];
761 };
762 
763 /// Read Multiple Response
764 struct l2cc_att_rd_mult_rsp
765 {
766     /// Read Multiple Response - 0x0F
767     uint8_t    code;
768     /// value length
769     uint16_t   value_len;
770     /// A set of two or more values.
771     uint8_t    value[__ARRAY_EMPTY];
772 };
773 
774 /// Read by Group Type Request
775 struct l2cc_att_rd_by_grp_type_req
776 {
777     /// Read by Group Type Request - 0x10
778     uint8_t     code;
779     /// First requested handle number
780     uint16_t    shdl;
781     /// Last requested handle number
782     uint16_t    ehdl;
783     /// Attribute uuid length
784     uint16_t    uuid_len;
785     /// Attribute type uuid (2 or 16 octet UUID)
786     uint8_t     uuid[__ARRAY_EMPTY];
787 };
788 
789 /// Read By Group Type Response
790 struct l2cc_att_rd_by_grp_type_rsp
791 {
792     /// Read By Group Type Response - 0x11
793     uint8_t     code;
794     /// size of each attribute handle listed
795     uint8_t     each_len;
796     /// Attribute Data length
797     uint16_t    data_len;
798     /// A list of Attribute Data.
799     uint8_t     data[__ARRAY_EMPTY];
800 };
801 
802 /// Write Request
803 struct l2cc_att_wr_req
804 {
805     /// Write Request - 0x12
806     uint8_t     code;
807     /// The handle of the attribute to be written
808     uint16_t    handle;
809     /// Value length
810     uint16_t    value_len;
811     /// The value to be written to the attribute
812     uint8_t     value[__ARRAY_EMPTY];
813 };
814 
815 /// Write Response
816 struct l2cc_att_wr_rsp
817 {
818     /// Write Response - 0x13
819     uint8_t     code;
820 };
821 
822 /// Write Command
823 struct l2cc_att_wr_cmd
824 {
825     /// Write Command - 0x52
826     uint8_t     code;
827     /// The handle of the attribute to be written
828     uint16_t    handle;
829     /// Value length
830     uint16_t    value_len;
831     /// The value to be written to the attribute
832     uint8_t     value[__ARRAY_EMPTY];
833 };
834 
835 /// Signed Write Command
836 struct l2cc_att_sign_wr_cmd
837 {
838     /// Write Command - 0xD2
839     uint8_t     code;
840     /// The handle of the attribute to be written
841     uint16_t    handle;
842     /// Attribute Data length
843     uint16_t    value_len;
844     /// The value to be written to the attribute
845     /// + 12 bytes of signatures:
846     /// Authentication signature for the Attribute Upload, Attribute Handle and Attribute
847     /// Value Parameters
848     uint8_t     value[__ARRAY_EMPTY];
849 };
850 
851 /// Prepare Write Request
852 struct l2cc_att_prep_wr_req
853 {
854     /// Prepare Write Request - 0x16
855     uint8_t     code;
856     /// The handle of the attribute to be written
857     uint16_t    handle;
858     /// The offset of the first octet to be written
859     uint16_t    offset;
860     /// Value length
861     uint16_t    value_len;
862     /// The value to be written to the attribute
863     uint8_t     value[__ARRAY_EMPTY];
864 };
865 
866 /// Prepare Write Response
867 struct l2cc_att_prep_wr_rsp
868 {
869     /// Prepare Write Response - 0x17
870     uint8_t     code;
871     /// The handle of the attribute to be written
872     uint16_t    handle;
873     /// The offset of the first octet to be written
874     uint16_t    offset;
875     /// Value length
876     uint16_t    value_len;
877     /// The value to be written to the attribute
878     uint8_t     value[__ARRAY_EMPTY];
879 };
880 
881 /// Execute Write Request
882 struct l2cc_att_exe_wr_req
883 {
884     /// Execute Write Request - 0x18
885     uint8_t     code;
886     /// 0x00 - Cancel all prepared writes
887     /// 0x01 - Immediately write all pending prepared values
888     uint8_t    flags;
889 };
890 
891 /// Execute Write Response
892 struct l2cc_att_exe_wr_rsp
893 {
894     /// Prepare Write Response - 0x19
895     uint8_t     code;
896 };
897 
898 /// Handle Value Notification
899 struct l2cc_att_hdl_val_ntf
900 {
901     /// Handle Value Notification - 0x1B
902     uint8_t     code;
903     /// The handle of the attribute to be written
904     uint16_t    handle;
905     /// Value length
906     uint16_t    value_len;
907     /// The current value of the attribute
908     uint8_t     value[__ARRAY_EMPTY];
909 };
910 
911 /// Handle Value Indication
912 struct l2cc_att_hdl_val_ind
913 {
914     /// Handle Value Indication - 0x1D
915     uint8_t     code;
916     /// The handle of the attribute to be written
917     uint16_t    handle;
918     /// Value length
919     uint16_t    value_len;
920     /// The current value of the attribute
921     uint8_t     value[__ARRAY_EMPTY];
922 };
923 
924 /// Handle Value Confirmation
925 struct l2cc_att_hdl_val_cfm
926 {
927     /// Handle Value Confirmation - 0x1E
928     uint8_t     code;
929 };
930 
931 /* LE Credit Based PDUs */
932 
933 /// LE Generic send data request  (includes total SDU Length)
934 struct l2cc_lecb_send_data_req
935 {
936     /// Code variable (RFU)
937     uint8_t code;
938     /// SDU data length
939     uint16_t sdu_data_len;
940     /// Data
941     uint8_t sdu_data[__ARRAY_EMPTY];
942 };
943 
944 
945 struct l2cc_pdu_data_t
946 {
947     /// L2Cap packet code.
948     uint8_t code;
949 };
950 
951 /// Default L2Cap PDU definition
952 struct l2cc_pdu
953 {
954     /// L2Cap Payload Length
955     uint16_t payld_len;
956     /// L2Cap Channel ID
957     uint16_t chan_id;
958 
959     /// Data PDU definition
960     union l2cc_pdu_data
961     {
962         /// L2Cap packet code.
963         uint8_t code;
964 
965         /* LE Credit Based packets */
966         /// LE send first frame
967         struct l2cc_lecb_send_data_req send_lecb_data_req;
968 
969         /* Connection Signaling Packets  */
970         /// Command Reject
971         struct l2cc_reject           reject;
972         /// Connection Parameter Update Request
973         struct l2cc_update_param_req update_req;
974         /// Connection Parameter Update Response
975         struct l2cc_update_param_rsp update_rsp;
976         /// LE Credit based connection request
977         struct l2cc_lecb_req credit_con_req;
978         /// LE Credit based connection response
979         struct l2cc_lecb_rsp credit_con_rsp;
980         /// LE Flow Control Credit
981         struct l2cc_le_flow_ctl_credit flow_ctl_credit;
982         /// LE disconnection request
983         struct l2cc_disconnection_req disc_req;
984         /// LE disconnection response
985         struct l2cc_disconnection_rsp disc_rsp;
986 
987         /* Security manager PDUs */
988         /// Pairing Request
989         struct l2cc_pairing_req      pairing_req;
990         /// Pairing Response
991         struct l2cc_pairing_rsp      pairing_rsp;
992         /// Pairing Confirm
993         struct l2cc_pairing_cfm      pairing_cfm;
994         /// Pairing Random
995         struct l2cc_pairing_random   pairing_random;
996         /// Pairing Failed
997         struct l2cc_pairing_failed   pairing_failed;
998         /// Encryption Information
999         struct l2cc_encryption_inf   encryption_inf;
1000         /// Master Identification
1001         struct l2cc_master_id        master_id;
1002         /// Identity Information
1003         struct l2cc_identity_inf     identity_inf;
1004         /// Identity Address Information
1005         struct l2cc_id_addr_inf      id_addr_inf;
1006         /// Signing Information
1007         struct l2cc_signing_inf      signing_inf;
1008         /// Security Request
1009         struct l2cc_security_req     security_req;
1010         /// Public Keys
1011         struct l2cc_publc_key              public_key;
1012         /// Key Press Notification
1013         struct l2cc_keypress_noticication  keypress_noticication;
1014         /// DH Key Check
1015         struct l2cc_dhkey_check               dhkey_check;
1016         /* Attribute protocol PDUs */
1017         /// Error response
1018         struct l2cc_att_err_rsp             err_rsp;
1019         /// Exchange MTU Request
1020         struct l2cc_att_mtu_req             mtu_req;
1021         /// Exchange MTU Response
1022         struct l2cc_att_mtu_rsp             mtu_rsp;
1023         /// Find Information Request
1024         struct l2cc_att_find_info_req       find_info_req;
1025         /// Find Information Response
1026         struct l2cc_att_find_info_rsp       find_info_rsp;
1027         /// Find By Type Value Request
1028         struct l2cc_att_find_by_type_req    find_by_type_req;
1029         /// Find By Type Value Response
1030         struct l2cc_att_find_by_type_rsp    find_by_type_rsp;
1031         /// Read By Type Request
1032         struct l2cc_att_rd_by_type_req      rd_by_type_req;
1033         /// Read By Type Response
1034         struct l2cc_att_rd_by_type_rsp      rd_by_type_rsp;
1035         /// Read Request
1036         struct l2cc_att_rd_req              rd_req;
1037         /// Read Response
1038         struct l2cc_att_rd_rsp              rd_rsp;
1039         /// Read Blob Request
1040         struct l2cc_att_rd_blob_req         rd_blob_req;
1041         /// Read Blob Response
1042         struct l2cc_att_rd_blob_rsp         rd_blob_rsp;
1043         /// Read Multiple Request
1044         struct l2cc_att_rd_mult_req         rd_mult_req;
1045         /// Read Multiple Response
1046         struct l2cc_att_rd_mult_rsp         rd_mult_rsp;
1047         /// Read by Group Type Request
1048         struct l2cc_att_rd_by_grp_type_req  rd_by_grp_type_req;
1049         /// Read By Group Type Response
1050         struct l2cc_att_rd_by_grp_type_rsp  rd_by_grp_type_rsp;
1051         /// Write Request
1052         struct l2cc_att_wr_req              wr_req;
1053         /// Write Response
1054         struct l2cc_att_wr_rsp              wr_rsp;
1055         /// Write Command
1056         struct l2cc_att_wr_cmd              wr_cmd;
1057         /// Signed Write Command
1058         struct l2cc_att_sign_wr_cmd         sign_wr_cmd;
1059         /// Prepare Write Request
1060         struct l2cc_att_prep_wr_req         prep_wr_req;
1061         /// Prepare Write Response
1062         struct l2cc_att_prep_wr_rsp         prep_wr_rsp;
1063         /// Execute Write Request
1064         struct l2cc_att_exe_wr_req          exe_wr_req;
1065         /// Execute Write Response
1066         struct l2cc_att_exe_wr_rsp          exe_wr_rsp;
1067         /// Handle Value Notification
1068         struct l2cc_att_hdl_val_ntf         hdl_val_ntf;
1069         /// Handle Value Indication
1070         struct l2cc_att_hdl_val_ind         hdl_val_ind;
1071         /// Handle Value Confirmation
1072         struct l2cc_att_hdl_val_cfm         hdl_val_cfm;
1073     } data;
1074 };
1075 
1076 /// Default L2Cap DBG pdu definition
1077 struct l2cc_dbg_pdu
1078 {
1079     /// Data length
1080     uint16_t length;
1081     /// data
1082     uint8_t data[__ARRAY_EMPTY];
1083 };
1084 
1085 /// Default L2Cap SDU definition
1086 struct l2cc_sdu;
1087 
1088 
1089 /// @} L2CC_PDU
1090 
1091 
1092 #endif /* _L2CC_PDU_H_ */
1093