1 /*
2  * Copyright 2022 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 #define LOG_TAG "bt_property"
18 
19 #include "test/headless/property.h"
20 
21 #include <map>
22 
23 #include "include/hardware/bluetooth.h"
24 #include "test/headless/log.h"
25 
26 using namespace bluetooth::test;
27 
28 namespace {
29 
30 // Map the bluetooth property names to the corresponding headless property
31 // structure factor
32 std::map<::bt_property_type_t,
33          std::function<headless::bt_property_t*(const uint8_t* data, const size_t len)>>
34         property_map = {
35                 {BT_PROPERTY_BDNAME,
__anon9e0c8d840202() 36                  [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
37                    return new headless::property::name_t(data, len);
38                  }},
39                 {BT_PROPERTY_BDADDR,
__anon9e0c8d840302() 40                  [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
41                    return new headless::property::bdaddr_t(data, len);
42                  }},
43                 {BT_PROPERTY_UUIDS,
__anon9e0c8d840402() 44                  [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
45                    return new headless::property::uuid_t(data, len);
46                  }},
47                 {BT_PROPERTY_CLASS_OF_DEVICE,
__anon9e0c8d840502() 48                  [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
49                    return new headless::property::class_of_device_t(data, len);
50                  }},
51                 {BT_PROPERTY_TYPE_OF_DEVICE,
__anon9e0c8d840602() 52                  [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
53                    return new headless::property::type_of_device_t(data, len);
54                  }},
55                 {BT_PROPERTY_SERVICE_RECORD,
__anon9e0c8d840702() 56                  [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
57                    return new headless::property::void_t(data, len, BT_PROPERTY_SERVICE_RECORD);
58                  }},
59                 {BT_PROPERTY_ADAPTER_BONDED_DEVICES,
__anon9e0c8d840802() 60                  [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
61                    return new headless::property::void_t(data, len,
62                                                          BT_PROPERTY_ADAPTER_BONDED_DEVICES);
63                  }},
64                 {BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT,
__anon9e0c8d840902() 65                  [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
66                    return new headless::property::void_t(data, len,
67                                                          BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT);
68                  }},
69                 {BT_PROPERTY_REMOTE_FRIENDLY_NAME,
__anon9e0c8d840a02() 70                  [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
71                    return new headless::property::void_t(data, len,
72                                                          BT_PROPERTY_REMOTE_FRIENDLY_NAME);
73                  }},
74                 {BT_PROPERTY_REMOTE_RSSI,
__anon9e0c8d840b02() 75                  [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
76                    return new headless::property::void_t(data, len, BT_PROPERTY_REMOTE_RSSI);
77                  }},
78                 {BT_PROPERTY_REMOTE_VERSION_INFO,
__anon9e0c8d840c02() 79                  [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
80                    return new headless::property::void_t(data, len,
81                                                          BT_PROPERTY_REMOTE_VERSION_INFO);
82                  }},
83                 {BT_PROPERTY_LOCAL_LE_FEATURES,
__anon9e0c8d840d02() 84                  [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
85                    return new headless::property::void_t(data, len, BT_PROPERTY_LOCAL_LE_FEATURES);
86                  }},
87                 {BT_PROPERTY_DYNAMIC_AUDIO_BUFFER,
__anon9e0c8d840e02() 88                  [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
89                    return new headless::property::void_t(data, len,
90                                                          BT_PROPERTY_DYNAMIC_AUDIO_BUFFER);
91                  }},
92                 {BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER,
__anon9e0c8d840f02() 93                  [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
94                    return new headless::property::void_t(
95                            data, len, BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER);
96                  }},
97                 {BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP,
__anon9e0c8d841002() 98                  [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
99                    return new headless::property::void_t(data, len,
100                                                          BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP);
101                  }},
102 };
103 
104 }  // namespace
105 
106 // Caller owns the memory
property_factory(const::bt_property_t & bt_property)107 headless::bt_property_t* bluetooth::test::headless::property_factory(
108         const ::bt_property_t& bt_property) {
109   const uint8_t* data = static_cast<uint8_t*>(bt_property.val);
110   const size_t size = static_cast<size_t>(bt_property.len);
111 
112   if (size > 0) {
113     log::assert_that(data != nullptr, "Property value pointer is null");
114   }
115 
116   const auto factory = property_map.find(bt_property.type);
117   if (factory != property_map.end()) {
118     return factory->second(data, size);
119   }
120   return new headless::property::void_t(data, size, bt_property.type);
121 }
122