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 "gd/os/log.h"
24 #include "include/hardware/bluetooth.h"
25 #include "test/headless/log.h"
26 
27 using namespace bluetooth::test;
28 
29 namespace {
30 
31 // Map the bluetooth property names to the corresponding headless property
32 // structure factor
33 std::map<::bt_property_type_t, std::function<headless::bt_property_t*(
34                                    const uint8_t* data, const size_t len)>>
35     property_map = {
36         {BT_PROPERTY_BDNAME,
__anon4b405c0e0202() 37          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
38            return new headless::property::name_t(data, len);
39          }},
40         {BT_PROPERTY_BDADDR,
__anon4b405c0e0302() 41          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
42            return new headless::property::bdaddr_t(data, len);
43          }},
44         {BT_PROPERTY_UUIDS,
__anon4b405c0e0402() 45          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
46            return new headless::property::uuid_t(data, len);
47          }},
48         {BT_PROPERTY_CLASS_OF_DEVICE,
__anon4b405c0e0502() 49          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
50            return new headless::property::class_of_device_t(data, len);
51          }},
52         {BT_PROPERTY_TYPE_OF_DEVICE,
__anon4b405c0e0602() 53          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
54            return new headless::property::type_of_device_t(data, len);
55          }},
56         {BT_PROPERTY_SERVICE_RECORD,
__anon4b405c0e0702() 57          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
58            return new headless::property::void_t(data, len,
59                                                  BT_PROPERTY_SERVICE_RECORD);
60          }},
61         {BT_PROPERTY_ADAPTER_SCAN_MODE,
__anon4b405c0e0802() 62          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
63            return new headless::property::void_t(data, len,
64                                                  BT_PROPERTY_ADAPTER_SCAN_MODE);
65          }},
66         {BT_PROPERTY_ADAPTER_BONDED_DEVICES,
__anon4b405c0e0902() 67          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
68            return new headless::property::void_t(
69                data, len, BT_PROPERTY_ADAPTER_BONDED_DEVICES);
70          }},
71         {BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT,
__anon4b405c0e0a02() 72          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
73            return new headless::property::void_t(
74                data, len, BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT);
75          }},
76         {BT_PROPERTY_REMOTE_FRIENDLY_NAME,
__anon4b405c0e0b02() 77          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
78            return new headless::property::void_t(
79                data, len, BT_PROPERTY_REMOTE_FRIENDLY_NAME);
80          }},
81         {BT_PROPERTY_REMOTE_RSSI,
__anon4b405c0e0c02() 82          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
83            return new headless::property::void_t(data, len,
84                                                  BT_PROPERTY_REMOTE_RSSI);
85          }},
86         {BT_PROPERTY_REMOTE_VERSION_INFO,
__anon4b405c0e0d02() 87          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
88            return new headless::property::void_t(
89                data, len, BT_PROPERTY_REMOTE_VERSION_INFO);
90          }},
91         {BT_PROPERTY_LOCAL_LE_FEATURES,
__anon4b405c0e0e02() 92          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
93            return new headless::property::void_t(data, len,
94                                                  BT_PROPERTY_LOCAL_LE_FEATURES);
95          }},
96         {BT_PROPERTY_DYNAMIC_AUDIO_BUFFER,
__anon4b405c0e0f02() 97          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
98            return new headless::property::void_t(
99                data, len, BT_PROPERTY_DYNAMIC_AUDIO_BUFFER);
100          }},
101         {BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER,
__anon4b405c0e1002() 102          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
103            return new headless::property::void_t(
104                data, len, BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER);
105          }},
106         {BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP,
__anon4b405c0e1102() 107          [](const uint8_t* data, const size_t len) -> headless::bt_property_t* {
108            return new headless::property::void_t(
109                data, len, BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP);
110          }},
111 };
112 
113 }  // namespace
114 
115 // Caller owns the memory
property_factory(const::bt_property_t & bt_property)116 headless::bt_property_t* bluetooth::test::headless::property_factory(
117     const ::bt_property_t& bt_property) {
118   const uint8_t* data = static_cast<uint8_t*>(bt_property.val);
119   const size_t size = static_cast<size_t>(bt_property.len);
120 
121   if (size > 0) {
122     log::assert_that(data != nullptr, "Property value pointer is null");
123   }
124 
125   const auto factory = property_map.find(bt_property.type);
126   if (factory != property_map.end()) {
127     return factory->second(data, size);
128   }
129   return new headless::property::void_t(data, size, bt_property.type);
130 }
131