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