1 /*
2  * Copyright 2021 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 "stack/include/hcidefs.h"
20 
21 #define BD_FEATURES_LEN 8
22 typedef uint8_t
23     BD_FEATURES[BD_FEATURES_LEN]; /* LMP features supported by device */
24 
25 // Bit order [0]:0-7 [1]:8-15 ... [7]:56-63
bd_features_text(const BD_FEATURES & features)26 inline std::string bd_features_text(const BD_FEATURES& features) {
27   uint8_t len = BD_FEATURES_LEN;
28   char buf[255];
29   char* pbuf = buf;
30   const uint8_t* b = features;
31   while (len--) {
32     pbuf += sprintf(pbuf, "0x%02x ", *b++);
33   }
34   return std::string(buf);
35 }
36 
37 /**
38  * Create a bitmask of packet types from the remote feature
39  */
40 class PeerPacketTypes {
41  public:
42   struct {
43     uint16_t supported{0};
44     uint16_t unsupported{0};
45   } acl{.supported = (HCI_PKT_TYPES_MASK_DM1 | HCI_PKT_TYPES_MASK_DH1)}, sco{};
46 
PeerPacketTypes(const BD_FEATURES & features)47   PeerPacketTypes(const BD_FEATURES& features) {
48     /* 3 and 5 slot packets? */
49     if (HCI_3_SLOT_PACKETS_SUPPORTED(features))
50       acl.supported |= (HCI_PKT_TYPES_MASK_DH3 | HCI_PKT_TYPES_MASK_DM3);
51 
52     if (HCI_5_SLOT_PACKETS_SUPPORTED(features))
53       acl.supported |= HCI_PKT_TYPES_MASK_DH5 | HCI_PKT_TYPES_MASK_DM5;
54 
55     /* 2 and 3 MPS support? */
56     if (!HCI_EDR_ACL_2MPS_SUPPORTED(features))
57       /* Not supported. Add 'not_supported' mask for all 2MPS packet types */
58       acl.unsupported |=
59           (HCI_PKT_TYPES_MASK_NO_2_DH1 | HCI_PKT_TYPES_MASK_NO_2_DH3 |
60            HCI_PKT_TYPES_MASK_NO_2_DH5);
61 
62     if (!HCI_EDR_ACL_3MPS_SUPPORTED(features))
63       /* Not supported. Add 'not_supported' mask for all 3MPS packet types */
64       acl.unsupported |=
65           (HCI_PKT_TYPES_MASK_NO_3_DH1 | HCI_PKT_TYPES_MASK_NO_3_DH3 |
66            HCI_PKT_TYPES_MASK_NO_3_DH5);
67 
68     /* EDR 3 and 5 slot support? */
69     if (HCI_EDR_ACL_2MPS_SUPPORTED(features) ||
70         HCI_EDR_ACL_3MPS_SUPPORTED(features)) {
71       if (!HCI_3_SLOT_EDR_ACL_SUPPORTED(features))
72         /* Not supported. Add 'not_supported' mask for all 3-slot EDR packet
73          * types
74          */
75         acl.unsupported |=
76             (HCI_PKT_TYPES_MASK_NO_2_DH3 | HCI_PKT_TYPES_MASK_NO_3_DH3);
77 
78       if (!HCI_5_SLOT_EDR_ACL_SUPPORTED(features))
79         /* Not supported. Add 'not_supported' mask for all 5-slot EDR packet
80          * types
81          */
82         acl.unsupported |=
83             (HCI_PKT_TYPES_MASK_NO_2_DH5 | HCI_PKT_TYPES_MASK_NO_3_DH5);
84     }
85   }
86 };
87