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