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