1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <bluetooth/log.h>
20 #include <stdbool.h>
21 
22 #include <cstdint>
23 
24 #include "stack/include/hcidefs.h"
25 #include "stack/include/l2cdefs.h"
26 
27 /* Validity check for PSM.  PSM values must be odd.  Also, all PSM values must
28  * be assigned such that the least significant bit of the most sigificant
29  * octet equals zero.
30  */
31 #define L2C_INVALID_PSM(psm) (((psm) & 0x0101) != 0x0001)
32 #define L2C_IS_VALID_PSM(psm) (((psm) & 0x0101) == 0x0001)
33 #define L2C_IS_VALID_LE_PSM(psm) (((psm) > 0x0000) && ((psm) < 0x0100))
34 
35 /* Define the minimum offset that L2CAP needs in a buffer. This is made up of
36  * HCI type(1), len(2), handle(2), L2CAP len(2) and CID(2) => 9
37  */
38 #define L2CAP_MIN_OFFSET 13 /* plus control(2), SDU length(2) */
39 
40 #define L2CAP_LCC_SDU_LENGTH 2
41 #define L2CAP_LCC_OFFSET (L2CAP_MIN_OFFSET + L2CAP_LCC_SDU_LENGTH) /* plus SDU length(2) */
42 
43 #define L2CAP_FCS_LENGTH 2
44 
45 /*****************************************************************************
46  *  Type Definitions
47  ****************************************************************************/
48 
49 /* Define the structure that applications use to create or accept
50  * connections with enhanced retransmission mode.
51  */
52 struct tL2CAP_ERTM_INFO {
53   uint8_t preferred_mode;
54 };
55 
56 /* Values for priority parameter to L2CA_SetAclPriority */
57 enum tL2CAP_PRIORITY : uint8_t {
58   L2CAP_PRIORITY_NORMAL = 0,
59   L2CAP_PRIORITY_HIGH = 1,
60 };
61 
62 /* Values for priority parameter to L2CA_SetAclLatency */
63 enum tL2CAP_LATENCY : uint8_t {
64   L2CAP_LATENCY_NORMAL = 0,
65   L2CAP_LATENCY_LOW = 1,
66 };
67 
68 #define L2CAP_NO_IDLE_TIMEOUT 0xFFFF
69 
70 /* L2CA_FlushChannel num_to_flush definitions */
71 #define L2CAP_FLUSH_CHANS_ALL 0xffff
72 #define L2CAP_FLUSH_CHANS_GET 0x0000
73 
74 /* Values for priority parameter to L2CA_SetTxPriority */
75 #define L2CAP_CHNL_PRIORITY_HIGH 0
76 #define L2CAP_CHNL_PRIORITY_LOW 2
77 
78 typedef uint8_t tL2CAP_CHNL_PRIORITY;
79 
80 typedef struct {
81 #define L2CAP_FCR_BASIC_MODE 0x00
82 #define L2CAP_FCR_ERTM_MODE 0x03
83 #define L2CAP_FCR_LE_COC_MODE 0x05
84 
85   uint8_t mode;
86 
87   uint8_t tx_win_sz;
88   uint8_t max_transmit;
89   uint16_t rtrans_tout;
90   uint16_t mon_tout;
91   uint16_t mps;
92 } tL2CAP_FCR_OPTS;
93 
94 /* default options for ERTM mode */
95 constexpr tL2CAP_FCR_OPTS kDefaultErtmOptions = {
96         L2CAP_FCR_ERTM_MODE,
97         10,    /* Tx window size */
98         20,    /* Maximum transmissions before disconnecting */
99         2000,  /* Retransmission timeout (2 secs) */
100         12000, /* Monitor timeout (12 secs) */
101         1010   /* MPS segment size */
102 };
103 
104 typedef struct {
105   uint8_t qos_flags;          /* TBD */
106   uint8_t service_type;       /* see below */
107   uint32_t token_rate;        /* bytes/second */
108   uint32_t token_bucket_size; /* bytes */
109   uint32_t peak_bandwidth;    /* bytes/second */
110   uint32_t latency;           /* microseconds */
111   uint32_t delay_variation;   /* microseconds */
112 } FLOW_SPEC;
113 
114 /* Define a structure to hold the configuration parameters. Since the
115  * parameters are optional, for each parameter there is a boolean to
116  * use to signify its presence or absence.
117  */
118 typedef struct {
119   tL2CAP_CFG_RESULT result; /* Only used in confirm messages */
120   bool mtu_present;
121   uint16_t mtu;
122   bool qos_present;
123   FLOW_SPEC qos;
124   bool flush_to_present;
125   uint16_t flush_to;
126   bool fcr_present;
127   tL2CAP_FCR_OPTS fcr;
128   bool fcs_present; /* Optionally bypasses FCS checks */
129   uint8_t fcs;      /* '0' if desire is to bypass FCS, otherwise '1' */
130   bool ext_flow_spec_present;
131   tHCI_EXT_FLOW_SPEC ext_flow_spec;
132   bool init_credit_present;
133   uint16_t init_credit;
134   uint16_t flags; /* bit 0: 0-no continuation, 1-continuation */
135 } tL2CAP_CFG_INFO;
136 
137 /* Define a structure to hold the configuration parameter for LE L2CAP
138  * connection oriented channels.
139  */
140 constexpr uint16_t kDefaultL2capMtu = 100;
141 constexpr uint16_t kDefaultL2capMps = 100;
142 
143 // This is initial amount of credits we send, and amount to which we increase
144 // credits once they fall below threshold
145 uint16_t L2CA_LeCreditDefault();
146 
147 // If credit count on remote fall below this value, we send back credits to
148 // reach default value.
149 uint16_t L2CA_LeCreditThreshold();
150 
151 // Max number of CIDs in the L2CAP CREDIT BASED CONNECTION REQUEST
152 constexpr uint8_t L2CAP_CREDIT_BASED_MAX_CIDS = 5;
153 
154 struct tL2CAP_LE_CFG_INFO {
155   tL2CAP_CFG_RESULT result{tL2CAP_CFG_RESULT::L2CAP_CFG_OK}; /* Only used in confirm messages */
156   uint16_t mtu{kDefaultL2capMtu};
157   uint16_t mps{kDefaultL2capMps};
158   uint16_t credits{L2CA_LeCreditDefault()};
159   uint8_t number_of_channels{L2CAP_CREDIT_BASED_MAX_CIDS};
160 };
161 
162 /* LE credit based L2CAP connection parameters */
163 constexpr uint16_t L2CAP_LE_MIN_MTU = 23;  // Minimum SDU size
164 constexpr uint16_t L2CAP_LE_MIN_MPS = 23;
165 constexpr uint16_t L2CAP_LE_MAX_MPS = 65533;
166 constexpr uint16_t L2CAP_LE_CREDIT_MAX = 65535;
167 
168 namespace std {
169 template <>
170 struct formatter<tL2CAP_LATENCY> : enum_formatter<tL2CAP_LATENCY> {};
171 template <>
172 struct formatter<tL2CAP_PRIORITY> : enum_formatter<tL2CAP_PRIORITY> {};
173 }  // namespace std
174